If I have const and non-const versions of a function that returns a span:
class Foo {
public:
std::span<int> myFunc() {
auto begin{vec.begin()};
auto end{vec.end()};
// Do some work that modifies begin and end.
return {begin, end};
}
std::span<const int> myFunc() const {
// Same as above
}
private:
std::vector<int> vec{1, 2, 3};
};
Is there any way to avoid duplicating the function bodies?
I tried the const_cast
approach, but got stuck on trying to cast the std::span
return value.
const_cast
method is fine as long as the returned value will not violate const
ness.
Conversion from span<T>
to span<const T>
is possible but not the other way around.
std::span<const int> Foo::myFunc() const
{
return const_cast<Foo*>(this)->myFunc();
}
Quoting from an answer to duplicate:
NOTE: It is important that you do NOT put the logic in the non-const function and have the const-function call the non-const function -- it may result in undefined behavior. The reason is that a constant class instance gets cast as a non-constant instance. The non-const member function may accidentally modify the class, which the C++ standard states will result in undefined behavior.
Therefore, you are advised to do the following.
std::span<int> Foo::myFunc()
{
std::span<const int> const_span = static_cast<const Foo*>(this)->myFunc();
return std::span<int>(const_cast<int*>(const_span.data()), const_span.size());;
}