我想创建一个模板化的类MyClass<T>
,我希望有一个模板化的构造函数,它将采用MyClass<U>
类型的单个参数,只有U
是{派生自T
(或与T
相同,在这种情况下基本上也充当复制构造函数)。如果不是,我想在编译时失败。此外,它将具有第二个模板化成员函数MyClass<U> convert<U>() const
,仅当U
派生自T
(或与T
相同时)才有效。这个函数的实际实现在这个时候并不重要,现在我只想弄清楚如何声明它们。
虽然在某些情况下,可以使用仅static_assert
std::is_base_of
而不std::enable_if
的{{1}}来使编译失败,但我想知道我是否可以实现使用std :: enable_if。
提前致谢
答案 0 :(得分:0)
您将在此处讨论第一个问题。 由于您无法明确指定构造函数的模板参数,因此必须从参数本身推断出它。
我现在已经尝试了一段时间,因为我很好奇,显然后续的代码无法正常工作:
class A {
public:
inline static std::string print() { return "A"; }
};
class B
: public A {
public:
// Consciously hidden parent "print()"
inline static std::string print() { return "B"; }
};
template <typename T>
class MyClass {
public:
explicit MyClass() {
std::cout << "Default of MyClass with " << T::print() << std::endl;
}
template <typename U>
MyClass(const typename std::enable_if<std::is_base_of<T, typename
U::internal_type>::value, U>::type& other) {
std::cout << "Copy constructor of equal or derived type!" <<
U::internal_type::print() << std::endl;
}
typedef T internal_type;
};
int main()
{
MyClass<A> a;
MyClass<B> b;
MyClass<A> cpa(a);
MyClass<A> cpb(b); // Error
}
重要的是这个:
template <typename U>
MyClass(const typename std::enable_if<std::is_base_of<T, typename U::internal_type>::value, U>::type& other) {
std::cout << "Copy constructor of equal or derived type!" <<
U::internal_type::print() << std::endl;
}
我定义了internal_type帮助器来执行对带有T = B 参数的 MyClass的MyClass-template参数的检查,这就出现了问题:
通常,我们从外部提供U,如果没有它,就不要做一些enable_if魔术。 在这种情况下,我们传递MyClass而没有任何关于U的信息,但是尝试从U中获取信息......
这至少是我现在从试图理解它的方式。
如果有效,则部分:
std::is_base_of<T, typename U::internal_type>::value
在我们的案例中,将被替换为
std::is_base_of<A, B>::value
应该给出真实的。 如果依次启用,则应该使用&#34; U&#34;,即MyClass并用它替换整个事物,相当于:
MyClass<A> {
//...
MyClass(const MyClass<B>& other) {
}
};
所以我认为至少构造函数是不可能的。
如果我错了并需要了解更多信息,那么模板元编程大师会纠正我:D