The following code is a snippet of a tuple-like class where it is possible to get a reference to a given type in the tuple, or if that type is not found, the provided default value will be returned instead.
If the default value is a lvalue a reference must be returned, if the default value is a rvalue then a rvalue must be returned.
The following code illustrates the problem I'm having:
struct Foo { Foo(int d) : data(d) {} template <typename T, typename TT> const TT get_or_default(TT&& t) const { return data; } template <typename T, typename TT> TT get_or_default(TT&& t) { return data; } int data; }; int main(int argc, char* argv[]) { int i = 6; const Foo foo1(5); Foo foo2(5); // compile error foofoo1.get_or_default<int>(i); // works foo1.get_or_default<int>(5); foo2.get_or_default<int>(i) = 4; foo2.get_or_default<char>('a'); return 0; } When compiling this I get the following error:
cxx.cxx:6:20: error: binding of reference to type 'int' to a value of type 'const int' drops qualifiers return data; ^~~~ cxx.cxx:23:14: note: in instantiation of function template specialization 'Foo::get_or_default<int, int &>' requested here foo1.get_or_default<int>(i); ^ 1 error generated.