I have the following code:
template <typename T>
void f1( T t )
{
std::cout << "f1( " << t << " ) called." << endl;
}
template <typename T>
void f2( T t )
{
std::cout << "f2( " << t << " ) called." << endl;
}
template <typename F, typename T>
void call( F && f, T t )
{
f( t );
}
template <typename T>
void foo( T t )
{
call( f1<T>, t ); // Why is <T> necessary?
// f1(t) is a valid expression!
call( f2<T>, t );
}
void bar()
{
foo( 1 );
}
In the function foo()
I need to specify the template argument, even though f1(t)
is a valid expression. That's kinda destroying some possibilities in my code. My questions:
(BTW: I'm currently using Visual Studio 2010 and I get the error C2896, if I leave the <T>
out.)
f1
is not a function, it's a template. You cannot pass a template as a function argument.
f1<T>
is a function, so it can be passed.
1. Why do I need to specify the template argument?
Well, f1
is not an object, but a function template. You can only pass objects to functions.
2. How can I work around that limitation? (C++11 or C++14 allowed).
Use an object with a templated operator()
. Just replace the definition of f1()
with
struct { template <typename T> void operator()( T t )
{
std::cout << "f1( " << t << " ) called." << endl;
} } f1;
and likewise for f2()
. In C++14 you can write it even nicer
static const auto f1 = []( auto t )
{
std::cout << "f1( " << t << " ) called." << endl;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With