0
template <typename T> struct s
{

};

template <> struct s<MyClass *>
{

};

... in main function
struct s<MyClass*> obj;

上面的代码可以编译,但我真的看不出完全专业化能做什么

template <> struct s<MyClass *>
{

};

我不能像这样添加指针变量(既不是常量也不是静态的)

template <> struct s<MyClass *obj > // ERROR
{

};

那么上面的专业化有什么意义呢?我不能使用 MyClass *“匿名”指针

4

2 回答 2

1

我不能像这样添加指针变量(既不是常量也不是静态的)

template <> struct s<MyClass *obj > // ERROR
[...]

你可能在这里有一个误解。如果您关心希望提供指向用户定义类的实例的指针作为非类型模板参数的用例,那么这与模板专业化无关。

特别是,根据 C++11 标准的第 14.3.2/1 段,考虑您可以将指向类的全局实例的指针指定为模板参数:

非类型、非模板模板参数的模板参数应为以下之一:

——对于整数或枚举类型的非类型模板参数,模板参数类型的转换常量表达式(5.19);或者

— 非类型模板参数的名称;或者

— 一个常量表达式 (5.19),它指定具有静态存储持续时间和外部或内部链接的对象或具有外部或内部链接的函数的地址,包括函数模板和函数模板 ID,但不包括非静态类成员,表示为 (忽略括号)作为 & id 表达式,但如果名称引用函数或数组,则 & 可以省略,如果相应的模板参数是引用,则应省略;或者

[...]

这可能是您想要实现的目标:

struct MyClass { };

MyClass c;

template<MyClass* p>
//       ^^^^^^^^ Non-type template argument 
struct s
{
    // Possibly work with p
};

int main()
{
    s<&c> obj;
}

关于模板专业化

关于您编写​​的代码,您的主模板可以处理任何类型:

template <typename T> struct s
{
    // Definition...
};

当用于实例化主模板的参数为MyClass*

template <> struct s<MyClass *>
{
     // Definition when the template argument is `MyClass*`
};

例如,您可以这样做:

struct MyClass { };

template <typename T> struct s
{
    void print() { cout << "Primary template!" << endl; }
};

template <> struct s<MyClass *>
{
    void print() { cout << "Specialization for MyClass*!" << endl; }
};

int main()
{
    s<int> obj;
    obj.print(); // Will print "Primary template!"

    s<MyClass*> obj;
    obj.print(); // Will print "Specialization for MyClass*!"
}

另请注意,专用模板的定义可能与主模板的定义完全不同:

template <typename T> struct s
{
    void print() { cout << "Primary template!" << endl; }
};

template <> struct s<MyClass *>
{
    void greet() { cout << "Specialization for MyClass*!" << endl; }
};

int main()
{
    s<int> obj;
    obj.print(); // Will print "Primary template!"

    s<MyClass*> obj;
    obj.greet(); // Will print "Specialization for MyClass*!"
    obj.print(); // ERROR! s<MyClass*> has no `print()` member function
}

当然,这只是类模板特化如何工作的一个示例。以我的方式区分主要模板和专用模板的定义没有任何用处。

但是,存在许多用于此的实际用例。例如,可以针对某些特定类型以完全不同的方式优化和重写通用算法。

模板专业化的另一个重要应用是定义特征,您可能想了解它。

于 2013-03-02T14:17:57.760 回答
0

当您实例化模板(隐式或显式)时,您提供了一个类型:

s<int> s1;
s<float> s2;
s<MyClass> s3;

这些对象都将是模板s的实例,分别T推导为intfloatMyClass。例如,如果s实际上是这样定义的:

template <typename T> struct s {
  T x;
};

然后该对象s1有一个名为xtype的成员ints2有一个名为xof type的成员float,还有一个名为 of types3的成员。xMyClass

您给出的显式特化的要点是提供s传递给模板参数的类型何时为 a 的不同实现MyClass*,如下所示:

s<MyClass*> s4;

例如,考虑一个如下所示的显式特化:

template <> struct s<MyClass*>
{
  int x;
};

s4尽管它的模板参数是,但该对象将MyClass*有一个名为xtype的成员int。我们特别说过“当模板参数类型为MyClass*时,结构将有一个成员int x。”

s4对象将使用 的显式特化s,而不是更通用的版本。当您知道模板参数是一个MyClass*.

于 2013-03-02T14:13:58.023 回答