I’m trying to work with a data structure that deals with tuples, however I need to make a “tuple” that is really extracting data from a global data structure, the data grabbed depending on the index of the value. It has worked fairly well so far with this simple setup:
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;
}
However, the data structure that I’m feeding these fake tuples to wants to use std::tr1::get, and my attempt to overload it has failed:
template<int _Idx> PseudoTuple::ReturnWrapper std::tr1::get(PseudoTuple& pseudotuple)
{
return pseudotuple[_Idx];
}
Saying it is “unable to match an existing function declaration”. The STL declarations are very confusing, and I’m unable to figure out what the problem is. This is in Visual C++ 2010, in case it matters. I’m worried about other tuple specific functions being called as well, but I hope that seeing how to make get work will show me how to make them work too (if needed).
edit: ecatmur suggested placing the function in the namespace:
namespace std
{
namespace tr1
{
template<int _Idx> PseudoTuple::ReturnWrapper get(PseudoTuple& pseudotuple)
{
return pseudotuple[_Idx];
}
}
}
Now I’m getting the error I had before, when there was no appropriate get function:
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'
edit 2: Ah, the order of definitions is wrong, I’m defining the function after it is used. I guess it works for structs like tuple_size but not functions.
To overload a free function, you need to supply a definition in the appropriate namespace:
Note that this is undefined behaviour per 17.6.4.2.1 [namespace.std]; the only code objects you are allowed to add to
stdor contained namespaces are template specializations on user-defined classes. It should be fine with the current standard, though, as all your arguments are user-defined types and there is no conflict with standard-defined code objects.