使用enable_if进行部分模板专业化
我试图了解如何使用 std::enable_if 的类型特征来“启用”类的部分专业化。这是我试图运行的示例代码。
#include <type_traits>
#include <iostream>
class AbstractFoo {
public:
virtual const char* name() const = 0;
};
template <typename T, typename Enable = void>
class Foo;
template <>
class Foo<int> : public AbstractFoo{
public:
const char* name() const override { return "int"; }
};
template <>
class Foo<char> : public AbstractFoo {
public:
const char* name() const override { return "char"; }
};
template <typename T>
class Foo<T, typename std::enable_if<std::is_enum<T>::value, T>::type> : public AbstractFoo {
public:
const char* name() const override { return "enum"; }
};
enum class MyEnum {
VAL1,
VAL2,
VAL3
};
int main() {
Foo<int> v1;
Foo<char> v2;
Foo<MyEnum> v3;
std::cout << "v1.name()=" << v1.name() << std::endl;
std::cout << "v2.name()=" << v2.name() << std::endl;
std::cout << "v3.name()=" << v3.name() << std::endl;
return 0;
};
我的目标是对某些类型(例如 int 和 char)进行特定的专业化,但是,如果类型是枚举,则使用我的部分专业化。但是,当我尝试编译此代码时,出现以下错误
错误:聚合“Foo v3”的类型不完整,无法 定义
这意味着我的专业没有被选择,因此永远不会被定义。我做错了什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在
Foo
的声明中,第二个模板参数默认为void
。这意味着以下变量:实际上是
现在的问题是:这是否对应于您想要的专业化?不是真的,因为在您对枚举的专门化中:
std::is_enum::value = true
当T = MyEnum
std::enable_if::value, T>::type = T = MyEnum
当
T=MyEnum
因此,对于
T=MyEnum
,您给出Foo
的专业化,它与变量不匹配多于。正如评论中所述,一个简单的解决方法是将特化声明为这样
,当
T=MyEnum
时,第二个模板参数为void
,因此它与变量声明匹配v3
。In the declaration of
Foo
the second template parameter defaults tovoid
. That means that the following variable:is actually
Now the question is: does this correspond to the specialization you want? Not really, because in your specialization for enum:
std::is_enum<T>::value = true
whenT = MyEnum
std::enable_if<std::is_enum<T>::value, T>::type = T = MyEnum
when
T=MyEnum
So, for
T=MyEnum
, your give the specialization forFoo<T, T>
, which does not match the variable above.As noted in a comment, a simple fix is to declare the specialization as
In this way, the second template parameter is
void
whenT=MyEnum
, so it matches the variable declaration ofv3
.