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