使用 enable_if 的部分模板专业化
Partial Template Specialization using enable_if
我正在尝试了解如何使用 std::enable_if 的类型特征来“启用”class 的部分特化。这是我试图开始工作的示例代码L
#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)进行特定的特化,但是,如果类型是枚举,则使用我的部分特化。但是,当我尝试编译此代码时,出现以下错误
error: aggregate 'Foo v3' has incomplete type and cannot be
defined
我认为这意味着我的专业没有被选择,因此永远不会被定义。我做错了什么?
在 Foo
的声明中,第二个模板参数默认为 void
。这意味着以下变量:
Foo<MyEnum> v3;
实际上是
Foo<MyEnum, void> v3;
现在的问题是:这符合你想要的专业化吗?不是真的,因为在你的枚举专业化中:
std::is_enum<T>::value = true
当 T = MyEnum
std::enable_if<std::is_enum<T>::value, T>::type = T = MyEnum
当 T=MyEnum
因此,对于 T=MyEnum
,您给出 Foo<T, T>
的特化,这与上面的变量不匹配。
如评论中所述,一个简单的解决方法是将专业化声明为
class Foo<T, typename std::enable_if<std::is_enum<T>::value>::type>
这样,当T=MyEnum
时,第二个模板参数是void
,所以匹配v3
.
的变量声明
我正在尝试了解如何使用 std::enable_if 的类型特征来“启用”class 的部分特化。这是我试图开始工作的示例代码L
#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)进行特定的特化,但是,如果类型是枚举,则使用我的部分特化。但是,当我尝试编译此代码时,出现以下错误
error: aggregate 'Foo v3' has incomplete type and cannot be defined
我认为这意味着我的专业没有被选择,因此永远不会被定义。我做错了什么?
在 Foo
的声明中,第二个模板参数默认为 void
。这意味着以下变量:
Foo<MyEnum> v3;
实际上是
Foo<MyEnum, void> v3;
现在的问题是:这符合你想要的专业化吗?不是真的,因为在你的枚举专业化中:
std::is_enum<T>::value = true
当T = MyEnum
std::enable_if<std::is_enum<T>::value, T>::type = T = MyEnum
当T=MyEnum
因此,对于 T=MyEnum
,您给出 Foo<T, T>
的特化,这与上面的变量不匹配。
如评论中所述,一个简单的解决方法是将专业化声明为
class Foo<T, typename std::enable_if<std::is_enum<T>::value>::type>
这样,当T=MyEnum
时,第二个模板参数是void
,所以匹配v3
.