Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not infer template parameter from constructor?

my question today is pretty simple: why can't the compiler infer template parameters from class constructors, much as it can do from function parameters? For example, why couldn't the following code be valid:

template <typename obj> class Variable {     obj data; public:     Variable(obj d) { data = d; } };  int main() {     int num = 2;     Variable var(num); // would be equivalent to Variable<int> var(num),     return 0;          // but actually a compile error } 

As I say, I understand that this isn't valid, so my question is why isn't it? Would allowing this create any major syntactic holes? Is there an instance where one wouldn't want this functionality (where inferring a type would cause issues)? I'm just trying to understand the logic behind allowing template inference for functions, yet not for suitably-constructed classes.

like image 867
GRB Avatar asked Jun 11 '09 23:06

GRB


People also ask

Why do we use template template parameter?

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

Can we pass Nontype parameters to templates?

Template non-type arguments in C++It is also possible to use non-type arguments (basic/derived data types) i.e., in addition to the type argument T, it can also use other arguments such as strings, function names, constant expressions, and built-in data types.

What is correct for template parameter?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

Can a template parameter be a function?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.


2 Answers

I think it is not valid because the constructor isn't always the only point of entry of the class (I am talking about copy constructor and operator=). So suppose you are using your class like this :

MyClass m(string s); MyClass *pm; *pm = m; 

I am not sure if it would be so obvious for the parser to know what template type is the MyClass pm;

Not sure if what I said make sense but feel free to add some comment, that's an interesting question.

C++ 17

It is accepted that C++17 will have type deduction from constructor arguments.

Examples:

std::pair p(2, 4.5); std::tuple t(4, 3, 2.5); 

Accepted paper.

like image 90
Drahakar Avatar answered Sep 21 '22 09:09

Drahakar


You can't do what you ask for reasons other people have addressed, but you can do this:

template<typename T> class Variable {     public: Variable(T d) {} }; template<typename T> Variable<T> make_variable(T instance) {   return Variable<T>(instance); } 

which for all intent and purposes is the same thing you ask for. If you love encapsulation you can make make_variable a static member function. That's what people call named constructor. So not only does it do what you want, but it's almost called what you want: the compiler is infering the template parameter from the (named) constructor.

NB: any reasonable compiler will optimize away the temporary object when you write something like

auto v = make_variable(instance); 
like image 33
Lionel Avatar answered Sep 21 '22 09:09

Lionel