我正在尝试使用处理元组的数据结构,但是我需要创建一个真正从全局数据结构中提取数据的“元组”,根据值的索引获取数据。到目前为止,它通过这种简单的设置运行得相当不错:
struct PseudoTuple
{
struct ReturnWrapper
{
//lots of operator overloads and fun stuff for comparisons
}
typedef ReturnWrapper value_type;
//pointers to global data and various info
static const size_t size = 9;
ReturnWrapper operator[](int index)
{
switch (index)
{
//routing to different values
}
}
}
template<> struct std::tr1::tuple_size<PseudoTuple>
{
static const size_t value = PseudoTuple::size;
}
然而,我正在为这些假元组提供的数据结构想要使用std::tr1::get
,而我尝试重载它的尝试失败了:
template<int _Idx> PseudoTuple::ReturnWrapper std::tr1::get(PseudoTuple& pseudotuple)
{
return pseudotuple[_Idx];
}
说它“无法匹配现有的函数声明”。 STL声明非常混乱,我无法弄清问题是什么。这是在Visual C ++ 2010中,如果它很重要。我担心其他元组特定函数也会被调用,但我希望看到如何使get
工作,这将告诉我如何让它们工作(如果需要)。
编辑:ecatmur建议将该函数放在命名空间中:
namespace std
{
namespace tr1
{
template<int _Idx> PseudoTuple::ReturnWrapper get(PseudoTuple& pseudotuple)
{
return pseudotuple[_Idx];
}
}
}
现在我收到了以前的错误,当时没有合适的get函数:
error C2784: '_Arg_traits<_Get<_Idx,tuple<_Arg0,_Arg1,_Arg2,_Arg3,_Arg4,_Arg5,_Arg6,_Arg7,_Arg8,_Arg9>::_MyImpl>::_Type>::_RType std::tr1::get(std::tr1::tuple<_Arg0,_Arg1,_Arg2,_Arg3,_Arg4,_Arg5,_Arg6,_Arg7,_Arg8,_Arg9> &)' : could not deduce template argument for 'std::tr1::tuple<_Arg0,_Arg1,_Arg2,_Arg3,_Arg4,_Arg5,_Arg6,_Arg7,_Arg8,_Arg9> &' from 'const PseudoTuple'
编辑2:啊,定义的顺序是错误的,我在使用它之后定义了这个函数。我想它适用于像tuple_size
这样的结构,但不适用于函数。
答案 0 :(得分:0)
要重载自由函数,需要在相应的命名空间中提供定义:
namespace std {
namespace tr1 {
template<int _Idx> PseudoTuple::ReturnWrapper get(PseudoTuple& pseudotuple)
{
return pseudotuple[_Idx];
}
template<int _Idx> ... get(const PseudoTuple &pseudotuple)
{
return ...;
}
template<int _Idx> ... get(PseudoTuple &&pseudotuple)
{
return ...;
}
}
}
请注意,根据 17.6.4.2.1 [namespace.std] ,这是未定义的行为;您可以添加到std
或包含的命名空间的唯一代码对象是用户定义类的模板特化。但是,使用当前标准应该没问题,因为所有参数都是用户定义的类型,并且与标准定义的代码对象没有冲突。