如何使用 std::enable_if 元函数实现 class 模板函数?
How can I implement a class template function with a std::enable_if metafunction?
我在我的 class 模板中使用了 std::enable_if
元函数来指定它只允许为以 GameCard
作为基础的变量生成 classes class。当我内联实现函数时,它本身就可以正常工作。但是,如果我想在 header body 之外实现模板函数,我会 运行 陷入无法弄清楚如何正确指定我想要实现的函数的问题。
删减示例代码:
#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 U>
bool CardStack<T, U>::Test() {
// body of function
}
解释很简单,这里没有反魔法。
只需遵循 C++.
的正常句法规则
你的 class 的定义是一个模板 class 有两个模板参数:
template<class, class>
struct CardStack { /* ... */ };
T
是第一个的名字。
另一方面,第二个没有任何类型名称,只有默认类型 (= ...
)。
默认类型(类似于函数的默认参数)不必在定义中指定。
因此,每个方法的定义应采用以下形式:
template <class T, class U>
bool CardStack<T, U>::MethodName() {}
class 的定义应该是:
template<class T, class Enabler>
bool CardStack<T, Enabler>::Test() {
return false;
}
但是目前,您 class 可能被劫持了:
而 CardStack<int>
或 CardStack<int, void>
由于 SFINAE 而无法编译,
CardStack<int, char>
将是 "valid"(由于 int
在 CardStack
实现中产生的硬错误而导致无法编译的风险).
static_assert
在你的情况下似乎足够了:
template<class T>
struct CardStack {
static_assert(std::is_base_of<GameCard, T>::value);
std::vector<T> cards;
bool Test();
};
class 定义更简单:
template<class T>
bool CardStack<T>::Test() {
return false;
}
我在我的 class 模板中使用了 std::enable_if
元函数来指定它只允许为以 GameCard
作为基础的变量生成 classes class。当我内联实现函数时,它本身就可以正常工作。但是,如果我想在 header body 之外实现模板函数,我会 运行 陷入无法弄清楚如何正确指定我想要实现的函数的问题。
删减示例代码:
#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 U>
bool CardStack<T, U>::Test() {
// body of function
}
解释很简单,这里没有反魔法。 只需遵循 C++.
的正常句法规则你的 class 的定义是一个模板 class 有两个模板参数:
template<class, class>
struct CardStack { /* ... */ };
T
是第一个的名字。
另一方面,第二个没有任何类型名称,只有默认类型 (= ...
)。
默认类型(类似于函数的默认参数)不必在定义中指定。
因此,每个方法的定义应采用以下形式:
template <class T, class U>
bool CardStack<T, U>::MethodName() {}
class 的定义应该是:
template<class T, class Enabler>
bool CardStack<T, Enabler>::Test() {
return false;
}
但是目前,您 class 可能被劫持了:
而 CardStack<int>
或 CardStack<int, void>
由于 SFINAE 而无法编译,
CardStack<int, char>
将是 "valid"(由于 int
在 CardStack
实现中产生的硬错误而导致无法编译的风险).
static_assert
在你的情况下似乎足够了:
template<class T>
struct CardStack {
static_assert(std::is_base_of<GameCard, T>::value);
std::vector<T> cards;
bool Test();
};
class 定义更简单:
template<class T>
bool CardStack<T>::Test() {
return false;
}