Consider the following class foo
:
class foo {
private:
int x = 0;
int y = 0;
public:
template <std::size_t I>
int const& get() const
{
if constexpr (I == 0) {
return x;
}
else return y;
}
};
I would like to implement structured bindings for foo
, so I added the following:
namespace std {
template <>
struct tuple_size<foo> : std::integral_constant<std::size_t, 2u> {};
template <std::size_t I>
struct tuple_element<I, foo> {
using type = int;
};
}
Now, if the user is to perform structure bindings, he/she has to explicitly add a const qualifier:
int main() {
foo f;
auto [a, b] = f; // Won't compile
auto& [x, y] = f; // Won't compile
const auto [c_a, c_b] = f; // Compiles
const auto& [c_x, c_y] = f; // Compiles
return 0;
}
(Because we cannot bind int&
to a int const&
)
Or, alternatively, I can make tuple_element
typedef a const int
. Now all four statements compiles:
namespace std {
template <>
struct tuple_size<foo> : std::integral_constant<std::size_t, 2u> {};
template <std::size_t I>
struct tuple_element<I, foo> {
using type = const int; // <=== const added here
};
}
int main() {
foo f;
auto [a, b] = f; // Compiles
auto& [x, y] = f; // Compiles
const auto [c_a, c_b] = f; // Compiles
const auto& [c_x, c_y] = f; // Compiles
return 0;
}
Now note that even if no const qualifier is present in their declarations, a
, b
, x
, and y
are all int const
. This might be confusing to the user.
So my question is: which one of the above is considered a better practice?