我在类模板中使用了std::enable_if
元函数来指定只允许为以GameCard
为基类的变量生成类。当我内联实现这些功能时,它本身可以很好地工作。但是,如果我想在标头主体之外实现模板功能,则会遇到无法解决如何正确指定要实现的功能的问题。
剪切示例代码:
#include <string>
#include <memory>
#include <vector>
struct GameCard {};
template<class T, class = std::enable_if_t<std::is_base_of<GameCard, T>::value>>
struct CardStack {
std::vector<T> cards;
bool Test();
};
我的IDE将此作为函数规范生成:
template<class T, class>
bool CardStack<T, <unnamed>>::Test() {
return false;
}
这显然是错误的,因为我遇到编译器错误。但是我不知道如何正确地做。你们中有人知道如何正确执行此操作吗?
超出类的定义应该是:
template<class T, class Enabler>
bool CardStack<T, Enabler>::Test() {
return false;
}
但是目前,您的课程可能已被劫持:
由于SFINAE,CardStack<int>
或CardStack<int, void>
无法编译,
CardStack<int, char>
将是“ valid”(由于[C0]实现中的int
产生硬错误,有可能无法编译的风险。
CardStack
在您的情况下似乎足够:
static_assert
使用更简单的类外定义:
template<class T>
struct CardStack {
static_assert(std::is_base_of<GameCard, T>::value);
std::vector<T> cards;
bool Test();
};
函数成员的定义应类似于:
template<class T>
bool CardStack<T>::Test() {
return false;
}
template <class T, class U>
bool CardStack<T, U>::Test() {
// body of function
}
解释非常简单,这里没有反魔术。只需遵循C ++的常规语法规则。
您的类的定义是带有两个模板参数的模板类:
Live example
template<class, class>
struct CardStack { /* ... */ };
是第一个的名称。另一方面,第二个没有任何类型名称,而只有默认类型(T
)。不必在定义中指定默认类型(类似于函数的默认参数)。
因此,每个方法定义应采用以下形式:
= ...