2013-03-02 62 views
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的*“匿名”指针

+0

想必如果您需要为MyClass *定制行为会很有用吗? – 2013-03-02 14:12:07

+2

基于这个和你以前的问题:你可能会误解模板的整个概念*。它们是*编译时*结构。 – delnan 2013-03-02 14:16:02

回答

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 
} 

当然,这仅仅是类模板专业化的运作方式。按照我所做的方式区分主模板和专用模板的定义没有任何用处。

然而,存在许多现实世界的用例。例如,对于某些特定类型,通用算法可能会以完全不同的方式进行优化和重写。

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

0

,你提供了一个类型:

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

这些对象将各自模板s的实例其中T分别推导为int,floatMyClass。例如,如果s实际上定义像这样:

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

然后对象s1有一个成员称为int类型的xs2有一个构件称为float类型的x,和s3具有构件称为类型的xMyClass

,你给一个明确的专业化的一点是要实现一个不同的s时传递给模板参数的类型是MyClass*,如:

s<MyClass*> s4; 

例如,考虑一个明确的专业化,看起来像:

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

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

这个s4对象将使用s的显式特化,而不是更一般的版本。当你知道模板参数是MyClass*时,也许你可以更有效地实现你的类。