我正在阅读关于有效c ++编程的Meyers一书,我在第25项中找到了total template specialization,但我无法理解,这是什么意思?他还举了一个例子:
namespace std {
template<>
void swap<Widget>(Widget& a, Widget& b)
{
swap(a.pimpl, b.pimpl);
}
}
Run Code Online (Sandbox Code Playgroud)
这句话意味着什么:( template<>为什么没有typename?)
提前致谢
In *_*ico 13
通常,您使用模板,因为您有一段足够通用的代码,可以应用于不同类型.但是,对于某些类型,您可能希望做一些不同的事情(例如,因为有一种更有效的方法).这是模板专业化拯救时(您可以将它们视为"特殊情况"模板):
例如:
class Foo {};
class Bar {};
// Primary template - the most generic.
template<typename T, typename U>
class MyClass
{
public:
void DoSomething()
{
/* Performs the same generic operation for all T and U... */
}
};
// Total specialization of the primary template
template<>
class MyClass<Foo, Bar>
{
public:
void DoSomething()
{
/* ...Except when T is Foo and U is Bar.
We may possibly do something different
to allow for higher efficiency. */
}
};
int main()
{
MyClass<int, char> a; // Uses the generic version of MyClass
MyClass<Foo, Bar> b; // Uses the (total) template specialization
}
Run Code Online (Sandbox Code Playgroud)
请注意,我在这里使用类,但概念是相同的.您可以看到类似的语法适用于函数模板.
但是,对于类,当模板特化中没有完全指定所有参数时,存在部分模板特化的事情.它可能看起来像这样:
// Partial specialization #1
template<typename U>
class MyClass<Foo, U>
{
public:
void DoSomething()
{
/* ...Do something special when T is Foo.
This code doesn't care what type U is. */
}
};
template<typename T> class Baz {};
// Partial specialization #2
template<typename Z>
class MyClass<Foo, Baz<Z> >
{
public:
void DoSomething()
{
/* ...Do something special when T is Foo, and U is Baz.
This code doesn't care what Baz gets for its
template parameter. */
}
};
int main()
{
MyClass<int, char> a; // Uses the generic version of MyClass
MyClass<Foo, char> b; // Uses partial template specialization #1
MyClass<Foo, Baz<int> > c; // Uses partial template specialization #2
MyClass<Foo, Bar> d; // Uses the total template specialization
}
Run Code Online (Sandbox Code Playgroud)
请注意,处理这些特化时没有歧义,因为编译器会选择最适合模板参数的特殊化.通过允许这些"特殊情况"模板,我们可以创建真正通用的库.
另请注意,此部分专业化业务仅适用于类,而不适用于函数!(您不能部分专门化功能模板).这就是为什么你的代码片段按原样编写的原因 - 你只能完全专门化函数模板 - 其他任何东西都是函数重载std命名空间中的(C++标准不允许).我花时间提到这一点,因为很多人似乎都错了.
namespace std
{
/* Do **not** do this in the std namespace!!!
You're not actually partially specializing the function,
you're overloading the function in the std namespace
which is prohibited by the C++ standard. */
template<typename T>
void swap<Widget<T> >(Widget<T>& a, Widget<T>& b) {}
}
Run Code Online (Sandbox Code Playgroud)