template< class T > class Foo { public: Foo( T t ) { } }; int main () { int i = 0; Foo f( i ); }
In the above code, the compiler complains that template arguments are missing before 'f'. I understand that deducing template arguments for a class from the arguments to the constructor is not part of the standard, but my question is why? Doesn't the compiler have all the information it needs to implicitly instantiate Foo<int>
and call its constructor?
Edited to make it clear that I'm calling the constructor with an int
(as opposed to a short
, long
, void*
, etc.)
The copy constructor lets you create a new object from an existing one by initialization. A copy constructor of a class A is a non-template constructor in which the first parameter is of type A& , const A& , volatile A& , or const volatile A& , and the rest of its parameters (if there are any) have default values.
You cannot give default arguments to the same template parameters in different declarations in the same scope. The compiler will not allow the following example: template<class T = char> class X; template<class T = char> class X { };
Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.
Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.
Because nobody has specified how exactly that works. There is a current proposal to the standard committee to make it work. It also lists some of the difficulties:
http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4471.html
Update: Here's the newest version of the proposal:
http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0091r0.html
TL;DR: Template specialization
They can, but only template arguments on the function itself, not on the type.
The declaration Foo f(0);
is illegal, because there is no type named Foo
. Perhaps you were thinking of
auto f = Foo(0);
but that is not allowed either, because the compiler doesn't know what scope to search in (there are infinite potential types with a constructor named Foo
and, with specialization, possibly more than one with a constructor Foo(int)
)
The usual method to do this is with a factory helper function:
auto f = make_foo(0);
where the factory function's return type depends on type deduction of its parameters.
You can imagine that the factory functions could be automatically generated in namespace scope and then the usual function overloading rules applied, but this runs into significant difficulty because there can be template arguments on both the type and the constructor itself. These could simply be concatenated, with the limitation that this would exclude class templates with variadic argument lists, because there would be no way to distinguish where the type parameters end and the function parameters begin.
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