Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't class template constructor arguments automatically determined? [duplicate]

Tags:

c++

templates

Consider the following class:

template<typename T1, typename T2>
class Pair
{
     public:
         T1 First;
         T2 Second;
         Pair(const T1 &First, const T2 &Second) : First(First), Second(Second) { }
}

The following is not allowed in c++:

auto p = Pair(10, 10);

Why isn't that allowed? the types can be completely determined from the constructor call.
I know there are workaround for that like:

template<typename T1, typename T2>
Pair<T1, T2> MakePair(const T1 &First, const T2 &Second)
{
    return Pair<T1, T2>(First, Second);
}

But why is that needed? Why doesn't the compiler just determine the type from the arguments just like it does from function template? You might say its because the standard doesn't allow it, so why doesn't the standard allow it?

Edit:
For those who say this is an example why this shouldn't be allowed:

template<typename T1, typename T2>
class Pair
{
     public:
         T1 First;
         T2 Second;
         Pair(const T1 &First, const T2 &Second) : First(First), Second(Second) { }
         Pair(const T2 &Second, const T1 &First) : First(First), Second(Second) { }
};

auto p = Pair(10,1.0);

I can do exactly this with function templates overloading:

template<typename T1, typename T2>
Pair<T1, T2> MakePair(const T1 &First, const T2 &Second)
{
    return Pair<T1, T2>(First, Second);
}
template<typename T1, typename T2>
Pair<T1, T2> MakePair(const T2 &Second, const T1 &First)
{
    return Pair<T1, T2>(First, Second);
}

Why is this allowed for functions but not for classes?

like image 637
Dani Avatar asked Oct 27 '11 19:10

Dani


People also ask

Can template class have constructor?

This is basically a default constructor for the basic types. We can use this technique in our template code to create default constructors. For any generic type, T, we can explicitly call its default constructor. Our Measurement template can now be constructed with any type that has a default constructor.

Does every class have a default constructor c++?

For example, all members of class type, and their class-type members, must have a default constructor and destructors that are accessible. All data members of reference type and all const members must have a default member initializer.

What happens if you do not provide any constructor to a class in c++?

Constructors are called by the compiler automatically; they are rarely called explicitly by the programmer. If you write no constructor, the compiler will provide your class with a default constructor.

Can I define my own constructor in c++?

No, the C++ compiler doesn't create a default constructor when we initialize our own, the compiler by default creates a default constructor for every class; But, if we define our own constructor, the compiler doesn't create the default constructor.


2 Answers

This is what Bjarne Stroustrup has to say on the matter:

Note that class template arguments are never deduced. The reason is that the flexibility provided by several constructors for a class would make such deduction impossible in many cases and obscure in many more.

like image 56
John Dibling Avatar answered Sep 30 '22 02:09

John Dibling


Consider the following.

template<typename T1, typename T2>
class Pair
{
     public:
         T1 First;
         T2 Second;
         Pair(const T1 &First, const T2 &Second) : First(First), Second(Second) { }
         Pair(const T2 &Second, const T1 &First) : First(First), Second(Second) { }
};

auto p = Pair(10,1.0);

Should p be a Pair<int,double> or a Pair<double,int>?

like image 24
Benjamin Lindley Avatar answered Sep 30 '22 03:09

Benjamin Lindley