Implicit constructor available for all types derived from Base excepted the current type?
Posted
by
Vincent
on Stack Overflow
See other posts from Stack Overflow
or by Vincent
Published on 2012-08-29T19:23:45Z
Indexed on
2012/08/29
21:38 UTC
Read the original article
Hit count: 202
The following code sum up my problem :
template<class Parameter>
class Base {};
template<class Parameter1, class Parameter2, class Parameter>
class Derived1 : public Base<Parameter>
{ };
template<class Parameter1, class Parameter2, class Parameter>
class Derived2 : public Base<Parameter>
{
public :
// Copy constructor
Derived2(const Derived2& x);
// An EXPLICIT constructor that does a special conversion for a Derived2
// with other template parameters
template<class OtherParameter1, class OtherParameter2, class OtherParameter>
explicit Derived2(
const Derived2<OtherParameter1, OtherParameter2, OtherParameter>& x
);
// Now the problem : I want an IMPLICIT constructor that will work for every
// type derived from Base EXCEPT
// Derived2<OtherParameter1, OtherParameter2, OtherParameter>
template<class Type, class = typename std::enable_if</* SOMETHING */>::type>
Derived2(const Type& x);
};
How to restrict an implicit constructor to all classes derived from the parent class excepted the current class whatever its template parameters, considering that I already have an explicit constructor as in the example code ?
EDIT : For the implicit constructor from Base, I can obviously write :
template<class OtherParameter> Derived2(const Base<OtherParameter>& x);
But in that case, do I have the guaranty that the compiler will not use this constructor as an implicit constructor for Derived2<OtherParameter1, OtherParameter2, OtherParameter>
?
EDIT2: Here I have a test : (LWS here : http://liveworkspace.org/code/cd423fb44fb4c97bc3b843732d837abc)
#include <iostream>
template<typename Type> class Base {};
template<typename Type> class Other : public Base<Type> {};
template<typename Type> class Derived : public Base<Type>
{
public:
Derived() {std::cout<<"empty"<<std::endl;}
Derived(const Derived<Type>& x) {std::cout<<"copy"<<std::endl;}
template<typename OtherType> explicit Derived(const Derived<OtherType>& x) {std::cout<<"explicit"<<std::endl;}
template<typename OtherType> Derived(const Base<OtherType>& x) {std::cout<<"implicit"<<std::endl;}
};
int main()
{
Other<int> other0;
Other<double> other1;
std::cout<<"1 = ";
Derived<int> dint1; // <- empty
std::cout<<"2 = ";
Derived<int> dint2; // <- empty
std::cout<<"3 = ";
Derived<double> ddouble; // <- empty
std::cout<<"4 = ";
Derived<double> ddouble1(ddouble); // <- copy
std::cout<<"5 = ";
Derived<double> ddouble2(dint1); // <- explicit
std::cout<<"6 = ";
ddouble = other0; // <- implicit
std::cout<<"7 = ";
ddouble = other1; // <- implicit
std::cout<<"8 = ";
ddouble = ddouble2; // <- nothing (normal : default assignment)
std::cout<<"\n9 = ";
ddouble = Derived<double>(dint1); // <- explicit
std::cout<<"10 = ";
ddouble = dint2; // <- implicit : WHY ?!?!
return 0;
}
The last line worry me. Is it ok with the C++ standard ? Is it a bug of g++ ?
© Stack Overflow or respective owner