Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't constructors deduce template arguments? [duplicate]

Tags:

c++

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.)

like image 918
Greg Wilbur Avatar asked Apr 16 '15 14:04

Greg Wilbur


People also ask

Can copy constructor be template?

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.

CAN default arguments be used with the template?

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 { };

What is Ctad c++?

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 do we use template template parameter?

Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.


2 Answers

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

like image 132
Sebastian Redl Avatar answered Sep 20 '22 17:09

Sebastian Redl


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.

like image 35
Ben Voigt Avatar answered Sep 17 '22 17:09

Ben Voigt