【发布时间】:2017-06-24 02:12:02
【问题描述】:
我正试图围绕模板专业化,我有点困惑(也许不理解 typename 实际上是什么,或者编译器期望什么)
示例 1(编译):
template <typename A, typename... Args>
class Example
{
public:
Example(){}
virtual ~Example(){}
};
template <typename A, typename... Args>
class Example<A, int, Args...>{
Example(){}
virtual ~Example(){}
};
示例 2(编译):
template <typename A, int, typename... Args>
class Example
{
public:
Example(){}
virtual ~Example(){}
};
template <typename A, typename... Args>
class Example<A, 2, Args...>{
Example(){}
virtual ~Example(){}
};
示例 3(失败):
template <typename A, typename... Args>
class Example
{
public:
Example(){}
virtual ~Example(){}
};
template <typename A, typename... Args>
class Example<A, 2, Args...>{
Example(){}
virtual ~Example(){}
};
错误是:
错误:“模板类示例”的模板参数列表中的参数 2 的类型/值不匹配
问题:
首先,我是泛型编程的新手,我希望我问的是正确的问题。编译器规范术语对我来说还是有点陌生。
- 发生了什么?编译器是否试图将常量视为 类型名称?
- 如果 typename 可以特化为 int,int 可以特化为 2,为什么 typename 不能特化为 2?
- 用 int 或 enum 专门化类的“正确”方法是什么?
- 我问对问题了吗?
谢谢
编辑/解决方案:
在我理解了发生的事情之后(来自 Yakk 的解释),这就是我的最终解决方案的样子。我在某处读到一位 C++ 大师的文章“您可以通过添加另一层抽象来解决任何问题”。现在我知道这意味着什么了:D
enum ETypes
{
UNKNOWN = 0,
INT = 1,
FLOAT = 2,
STRING = 3,
FUNC = 4,
};
// This is to use the ETypes as a type.
// Note that T is not a type, hence use it as RHS
template<ETypes T>
class ETypeName
{
public:
ETypes type = T;
};
// The example
template <typename A, typename... Args>
class Example
{
private:
Example(); // Hide the constructor as private
// to generate compilation error
virtual ~Example(){}
};
// LOOK! We can use the Enum to specialize the class.
template <>
class Example<ETypeName<ETypes::INT>>{
public:
ETypes mType;
Example():mType(ETypes::INT){}
virtual ~Example(){}
};
在 main() 中:
Example<ETypeName<ETypes::INT>> x;
// This can't happen. Private constructor. Not specialized yet
// Example<ETypeName<ETypes::FLOAT>> x1;
【问题讨论】:
-
非类型模板参数与类型模板参数不同。本质上是的,2 被视为非类型参数,但模板类需要一个类型。
-
啊,这是我错过的东西
标签: c++11 templates specialization variadic