Reputation: 465
Why compiler can't find match and instantiate automatically?
template <typename T1, typename T2>
struct A
{
A( const T1& t1_, const T2& t2_ )
: t1( t1_ ), t2( t2_ )
{}
T1 t1;
T2 t2;
};
int main()
{
double d = 5.2;
std::string s( "hi" );
A a( d, s ); // this doesn't compile (gcc)
A<double, std::string> a1(d, s); // OK
}
Compile error from gcc: error: missing template arguments before 'a' error: expected ';' before 'a'
Upvotes: 0
Views: 112
Reputation: 3301
It didn't work because you didn't specify the parameterized types. You might think you did, but all you specified were constructor arguments, not template arguments. There could conceivably be a template specialized constructor of struct A
with the same constructor arguments but different template arguments.
Sure, the compiler could have tried to deduce the type from the arguments and compile without warning if it finds a unique match, but wouldn't that be a ticking time bomb waiting to blow up the instant you make this constructor: A< int, string >::A ( double, string )
?
In fact, I think the other reply suggesting a make_A()
function is asking for trouble too. Somewhere buried your code you might have a make_A(5,"whatever")
, blowing up somewhere far downstream. If you don't like to type it out, why not use a typedef
or using
? I've always found auto
to require vastly more effort to read.
Upvotes: 1
Reputation: 44
It seems as though any object of type A should have two arguments, i.e. double and std::string.
The line of code that does not compile does not utilize these arguments.
Upvotes: -1
Reputation: 72271
Template parameter deduction only happens for calls to function templates. If something like your example were allowed, it would at best be very confusing when you add complications like multiple class constructors, constructors that use the template arguments in a different order, in different ways, or not at all.
In cases like this, we'll often use a "make" function to complement the class template:
template <typename T1, typename T2>
A<T1, T2> make_A( const T1& t1, const T2& t2 )
{ return A<T1, T2>( t1, t2 ); }
int main()
{
double d = 5.2;
std::string s( "hi" );
auto a = make_A( d, s );
}
Upvotes: 2