是否可以为所有派生类型定义一个构造函数和一个模板构造函数? 我写了这个测试用例来说明我的问题:
#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
来禁止使用 T
派生自 Variant
的模板:
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;
}
当 T
派生自 Variant
时,这使得模板不可实例化,因此在重载解析期间它将不可用。 enable_if
和 is_base_of
是 C++0x 中 C++ 的新功能,您的编译器和标准库可能支持它们。如果没有,您也可以在 C++ TR1 或 Boost.TypeTraits 中找到它们.
关于c++ - 更改构造函数优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5720539/