我正在尝试支持类的类似元组的结构化绑定访问。为简单起见,我将在本文的其余部分使用以下类:
struct Test
{
int v = 42;
};
(我知道这个类支持开箱即用的结构化绑定,但我们假设它不支持。)
要启用对 的成员的类似元组的访问Test
,我们必须专门化std::tuple_size
和std::tuple_element
:
namespace std
{
template<>
struct tuple_size<Test>
{
static const std::size_t value = 1;
};
template<std::size_t I>
struct tuple_element<I, Test>
{
using type = int;
};
}
我们需要的最后一部分是或 的命名空间中的Test::get<i>
一个函数。让我们实现后者:get<i>(Test)
Test
template<std::size_t I>
int get(Test t)
{
return t.v;
}
这行得通。但是,我想返回对Test
的成员的引用std::get(std::tuple)
,例如 。因此,我实现get
如下:
template<std::size_t I>
int& get(Test& t)
{
return t.v;
}
template<std::size_t I>
const int& get(const Test& t)
{
return t.v;
}
但是,对于此版本,以下代码
auto test = Test{};
auto [v] = test;
产生错误(GCC 7.1):
将 'std::tuple_element<0, Test>::type& {aka int&}' 类型的引用绑定到 'const int' 丢弃限定符
因此,似乎为get<i>(const Test&)
结构化绑定选择了重载。由于此重载返回 a const int&
,并且v
像对 的非const
引用一样int
,因此代码无法编译。
然而,据此,该行auto [v] = test;
应该大致相当于
auto e = test;
std::tuple_element<0, Test>::type& v = get<0>(e)
这确实有效,因为它使用了get<i>(Test&)
重载。
关于为什么我的实现get
不适用于结构化绑定的任何想法?