C++ 使用std::enable_if启用模板化构造函数和返回另一个模板化实例的函数
我想创建一个模板化类,C++ 使用std::enable_if启用模板化构造函数和返回另一个模板化实例的函数,c++,c++11,templates,enable-if,C++,C++11,Templates,Enable If,我想创建一个模板化类,MyClass,其中我想有一个模板化构造函数,它将接受一个类型为MyClass的参数,只有当U是从T派生的(或者与T相同,在这种情况下基本上也充当副本构造函数)时,它才会工作。如果不是,我希望在编译时失败。此外,它还有第二个模板成员函数,MyClass convert()const,仅当U是从T派生的(或与T相同)时,该函数才起作用。目前这些函数的实际实现并不重要,现在我只是想弄清楚如何声明它们 虽然在某些情况下,可以使用static\u assert和std::is\u
MyClass
,其中我想有一个模板化构造函数,它将接受一个类型为MyClass
的参数,只有当U
是从T
派生的(或者与T
相同,在这种情况下基本上也充当副本构造函数)时,它才会工作。如果不是,我希望在编译时失败。此外,它还有第二个模板成员函数,MyClass convert()const
,仅当U
是从T
派生的(或与T
相同)时,该函数才起作用。目前这些函数的实际实现并不重要,现在我只是想弄清楚如何声明它们
虽然在某些情况下,可以使用static\u assert
和std::is\u base\u of
而不使用std::enable\u if
使编译失败,但我想知道使用std::enable\u if是否可以实现稍微更健壮的功能
提前感谢使用不同模板参数的类模板中的模板化构造函数
你将在这里讨论第一个问题。
由于无法显式指定构造函数的模板参数,因此必须从参数本身推导出模板参数
我试了一会儿,因为我很好奇,很明显后续的代码无法工作:
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
}
A类{
公众:
内联静态std::string print(){返回“A”;}
};
B类
:公众A{
公众:
//有意识地隐藏父项“print()”
内联静态std::string print(){返回“B”;}
};
模板
类MyClass{
公众:
显式MyClass(){
std::cout那么问题是什么呢?通常,如果你使用来约束模板,那么启用它。你是否绑定了它,但它不起作用?首先确保你理解静态断言和约束模板之间的区别。前者会导致硬错误,后者会使你的构造函数可检测。也就是说,问题N代码> ISS-可构造的< /代码>有不同的答案,你需要首先决定你想要的行为。我一直试图从我在StruouStrup的C++编程语言的第四版中找到的例子中推广,但没有任何运气…我尝试了几种我可以想到的排列,使用<代码> STD::std::enable_if
,但到目前为止我所尝试的都没有成功。我使用的是gcc 5.3,并使用-std=c++11进行编译,所以我应该有c++11功能可用。
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;
}
std::is_base_of<T, typename U::internal_type>::value
std::is_base_of<A, B>::value
MyClass<A> {
//...
MyClass(const MyClass<B>& other) {
}
};