I have a template of template function template< template< class > class Timg, class T > Timg< T > foo()
for which the compiler cannot deduce types. I can call this function with foo< object, T >()
, where object
is a template class. I would like to be able to call this function using decltype
, or something similar.
Here an example: The first file is header.h
template< class T >
class object
{
};
template< template< class > class Timg, class T >
Timg< T > foo()
{
return Timg< T >();
}
The second file is main.cpp
#include "header.h"
int main()
{
object< float > o;
auto l_return = foo< object, float >(); // OK
auto l_return2 = foo< decltype(o), float >(); // What I would like to achieve
return 0;
}
The problem here is that decltype(o)
returns object< float >
, but I would like to have only object
.
How can I deduce type from variable o
to pass it as template parameter for the function foo
?
object
is a class template, not a type. Only the instance of a class template is a type. object<float>
is a type. The template itself is not, it's a template…
I'm not aware of any way to directly deduce the original template a type was instantiated from. What you could do is define a helper class template and partially specialize to match the case that the parameter type is an instance of a template with a single type parameter. That way, you can deduce both, the template as well as the parameter type of a given object
instance. Inside this helper template, you could then have a member alias template that will give you an object
instance again as well as an alias to forward the parameter type
template <class T>
struct deduce_object_template;
template <template <class> class O, class V>
struct deduce_object_template<O<V>>
{
template <class T>
using object_t = O<T>;
using type = V;
};
and then use that to call foo
like so:
foo<deduce_object_template<T>::template object_t, typename deduce_object_template<T>::type>();
However, I would seriously question whether there's not a simpler way to achieve whatever it is that you want to achieve. Do you really need to deduce template and argument type? If all you want is create an object of whatever the type parameter was, why not simply define a second template
template <class Timg>
Timg foo()
{
return Timg();
}
and call foo<decltype(o)>();
?