For the life of me I can't seem to create a temporary of this class, why isn't it allowing me to?
template <typename T>
struct Dog
{
Dog(T t) : tag(t) {}
T tag;
};
int main()
{
int tag = 6;
Dog<int>(6); // Works fine
Dog<int>(tag); // On Visual Studio I get no default constructor exists for class Dog<int>
// On onlineGDB I get error: no matching function for call to ‘Dog::Dog()’
}
Also, what's the difference here, again between rvalue and lvalue:
Dog(6); // Deduces fine
Dog(tag); // Deduction fail, error: missing template arguments before ‘(’ token
Also:
Dog<int>{tag}; // Works.
I take it because this is aggregate initialization?
Dog(6);
and Dog<int>(6);
declare temporary Dog<int>
s, constructed with the value 6. Template argument deduction works fine in the first case, and the template parameter is explicit in the second.
However, Dog(tag);
is not creating a temporary. It's a declarator of a variable tag
of type Dog<?>
. In general, the parentheses are redundant, i.e.
int x
, int (x)
, int ((x))
are all equivalent. In this case, the error is that you haven't given an initializer with which to deduce the template parameter of Dog
. The other error is you can't have parentheses around declarators where you're doing class template argument deduction.
Dog<int>(tag);
is similar, it's a declarator of a variable tag
of type Dog<int>
. No deduction needs to be done since the parameter is explicit, but the error here is that you don't have a default constructor for Dog
, and you haven't provided an argument for the constructor yourself.
Dog{tag};
doesn't have the same issue as with parentheses. It declares a temporary Dog
constructed with tag
as you expected.