I have a problem related to type deduction from a function return value.
First, some context, to show what I expect. Say I have this function template:
template <typename T1, typename T2>
T1 foo( T2 t )
{
T1 a = static_cast<T1>(t); // dummy conversion,
return a; // just there to use t
}
then, this does not build, because return type can't be used for type deduction:
int a;
float v1 = foo(a);
char v2 = foo(a);
But if I add the requested type, then it's okay:
int a;
auto v1 = foo<float>(a);
auto v2 = foo<char>(a);
Now my problem. I have a class, that provides a getter to some data:
template<typename T>
struct MyClass
{
T data;
template<typename U>
U get() { return static_cast<U>(data); } // dummy code, returns an 'U'
};
User code can fetch the data with this (builds fine):
MyClass<int> m;
auto v3 = m.get<float>();
But I want to provide to user code a second way to access the data, by using a free function, so one can write:
MyClass<int> m;
auto v4 = ff_get<float>(m);
The question is:
How do I write ff_get()?
I tried:
template <typename T1, typename T2>
T1 ff_get( T2 t )
{
return t.get<T1>();
}
But this will not build, although it seems to me is uses the same syntax as the foo call above. So second part of the question is: why does this fail?
(see live code)
Convert the return type rather than deduce it
You can create a conversion proxy object for your return type. This moves the return type deduction into a template conversion operation instead.
Applied to
MyClass, your getter could be implemented similarly:And then, this code would work just fine:
Deduce the return type of the getter
Now, to implement
ff_get, it is mostly a trivial function implementation, except that the return type is now deduced from thegetmethod itself. In C++11, you would use the trailing return type syntax.Starting from C++ 14, you can drop the trailing return type altogether, since there is no ambiguity in the return type.