更改构造函数优先级

|| 是否可以为所有派生类型定义一个构造函数和一个模板构造函数? 我已经编写了这个测试用例来说明我的问题:
#include <iostream>


class Variant;
class CustomVariant;


class Variant
{
public:
    Variant(void)
        {}


    Variant(const Variant&)
        {
            std::cout << \"ctor\" << std::endl;
        }


    Variant(const CustomVariant&)
        {
            std::cout << \"custom\" << std::endl;
        }


    template<typename T>
    Variant(const T&)
        {
            std::cout << \"template\" << std::endl;
        }
};


class CustomVariant : public Variant
{
};


class DerivedVariantA : public CustomVariant
{
};


class DerivedVariantB : public CustomVariant
{
};


int main(void)
{

    DerivedVariantB dvb;

    Variant v(dvb);
    // expcected output: \"custom\" instead of \"template\"

}
    
已邀请:
template <typename T> Variant(const T&)  // (a)
Variant(const CustomVariant&)            // (b)
无需转换即可致电(a);参数类型
DerivedVariantB
是精确匹配,
T = DerivedVariantB
。 调用(b)需要派生到基本的转换。因此,(a)比(b)更好。 如果您使用类型为
CustomVariant
的参数调用构造函数,则两个构造函数都是完全匹配的,因此选择(b),因为在其他所有条件相等的情况下,非模板优先于模板。 您可以使用
std::enable_if
禁止使用从
Variant
衍生
T
的模板:
template<typename T>
Variant(const T&, 
        typename std::enable_if<
                     !std::is_base_of<Variant, T>::value, void*
                 >::type = 0)
{
    std::cout << \"template\" << std::endl;
}
这使得从
Variant
派生
T
时模板无法实例化,因此在过载解析期间将无法使用该模板。 ѭ11和ѭ12是C ++ 0x中C ++的新增功能,您的编译器和标准库可能支持它们。如果没有,您也可以在C ++ TR1或Boost.TypeTraits中找到它们。     
不,在该类可用的构造函数列表中,没有构造函数将类型为“ 2”的实例作为参数。因此,生成的模板被调用。
class DerivedVariantB ; // Forward Declaration

class Variant
{
    public:
    // ...

     Variant( const DerivedVariantB &obj )
     {
         std::cout << \"\\n DerivedVariantB \\n\";
     }
};
现在,可以调用采用类型为2的引用的构造函数,而不是使用模板生成的构造函数。     

要回复问题请先登录注册