请考虑以下代码:
template<typename T> class Base
{
Base();
Base(const Base<T>& rhs);
template<typename T0> explicit Base(const Base<T0>& rhs);
template<typename T0, class = typename std::enable_if<std::is_fundamental<T0>::value>::type> Base(const T0& rhs);
explicit Base(const std::string& rhs);
};
template<typename T> class Derived : Base<T>
{
Derived();
Derived(const Derived<T>& rhs);
template<class T0> Derived(const T0& rhs) : Base(rhs);
// Is there a way to "inherit" the explicit property ?
// Derived(double) will call an implicit constructor of Base
// Derived(std::string) will call an explicit constructor of Base
};
有没有办法以Derived
将Base
的所有构造函数具有相同的显式/隐式属性的方式重新设计此代码?
答案 0 :(得分:6)
C ++ 11提供this as a feature。然而,即使GCC实际上还没有实现它。
实际实施时,它看起来像这样:
template<typename T> class Derived : Base<T>
{
using Base<T>::Base;
};
话虽如此,但对你的案子可能没有帮助。继承的构造函数是一个全有或全无的命题。您可以使用它们的参数来获取所有基类构造函数。另外,如果您定义的构造函数与继承的构造函数具有相同的签名,则会出现编译错误。
答案 1 :(得分:2)
检测SFINAE的隐式/显式可构造性:
template<class T0, typename std::enable_if<
std::is_convertible<const T0 &, Base<T>>::value, int>::type = 0>
Derived(const T0& rhs) : Base<T>(rhs) { }
template<class T0, typename std::enable_if<
std::is_constructible<Base<T>, const T0 &>::value
&& !std::is_convertible<const T0 &, Base<T>>::value, int>::type = 0>
explicit Derived(const T0& rhs) : Base<T>(rhs) { }
使用std::is_convertible
检查隐式可兑换性的事实,并使用std::is_constructible
另外检查显式可兑换性。
使用boost::enable_if not in function signature中的解决方案修改enable_if
模板参数。
检查:
Derived<int>{5}; // allowed
[](Derived<int>){}(5); // allowed
Derived<int>{std::string{"hello"}}; // allowed
[](Derived<int>){}(std::string{"hello"}); // not allowed