模板参数的专门化
Specialization of template template parameters
这是前一个问题的后续问题(关于不同的主题)。下面的代码包含了Dehstil使用专门化的建议。
一个有模板模板参数的函数应该如何专门化?
下面的代码(其中两个专门化行没有编译)使问题具体化了。
#include <cassert>
template<typename S> struct PA1 {};
template<typename S> struct PA2 {};
template<typename S> struct PB {};
template<typename S> struct PC {};
template<typename S> struct A1 { typedef PA1<S> P; };
template<typename S> struct A2 { typedef PA2<S> P; };
template<typename S> struct B { typedef PB <S> P; };
template<typename S> struct C { typedef PC <S> P; };
template<typename S, template<typename> class T> char fn(typename T<S>::P);
template<typename S, template<typename> class T> char fn(typename T<S>::P)
{
return 'a';
}
template<typename S> char fn<B<S> >(B<S>::P) { return 'b'; }
template<typename S> char fn<C<S> >(C<S>::P) { return 'c'; }
int main()
{
PA1<int> pa1;
PA2<int> pa2;
PB<int> pb;
PC<int> pc;
assert( (fn<int, A1>(pa1)) == 'a' );
assert( (fn<int, A2>(pa2)) == 'a' );
assert( (fn<int, B>(pb)) == 'b' );
assert( (fn<int, C>(pc)) == 'c' );
}
四个函数调用fn<…,…>()在调用时具有相同的签名是很重要的,因为它们本身将驻留在应用于四个类A1/A2/B/c的模板类中。
c++标准不允许函数模板的部分特化!
重载你的函数而不是专门化它们。
阅读为什么不特化函数模板的解释?
然后阅读为什么要重载而不是专门化:模板专门化和重载by Herb Sutter
如何在重载
时统一调用所有函数编写一个类模板call
并将其特化为:
template<class S, template<typename> class T>
struct call
{
static char fn(typename T<S>::P &p)
{
return ::fn<S,T>(p);
}
};
template<class S>
struct call<S,B>
{
static char fn(typename B<S>::P &p)
{
return ::fn<S>(p);
}
};
template<class S>
struct call<S,C>
{
static char fn(typename C<S>::P &p)
{
return ::fn<S>(p);
}
};
然后你可以使用这个类模板统一调用所有的函数:
assert( (call<int, A1>::fn(pa1)) == 'a' );
assert( (call<int, A2>::fn(pa2)) == 'a' );
assert( (call<int, B>::fn(pb)) == 'b' );
assert( (call<int, C>::fn(pc)) == 'c' );
查看在线演示:http://www.ideone.com/TISIT
还请注意ideone.com(上面的链接)完整解决方案中的重载函数模板
函数只能完全特化。使用函数重载:
template<typename S> char fn(typename B<S>::P) { return 'b'; }
template<typename S> char fn(typename C<S>::P) { return 'c'; }
相关文章:
- 是否可以对零模板参数进行模板专门化
- 我能否根据其运算符()的签名专门化可变参数模板参数
- 取消专门化C++模板参数
- 模板函数,其中一个参数需要专门化,而另一个不需要
- 如何为特定数量的模板参数专门化可变参数模板结构
- 使用非类型模板参数进行专门化模板模板参数
- g++和clang++在结构/类专门化中具有非类型参数的不同行为
- 我如何避免使用依赖于参数的查找明确专门化模板化功能
- 专门化采用通用引用参数的函数模板
- 如果需要参数包,则使用SFINAE专门化类
- c++多参数模板化的类成员专门化
- C++11`using`关键字:专门化模板参数的模板别名
- 如何在没有参数的情况下专门化模板类
- 我可以用非模板类专门化一个可变模板模板模板参数吗
- 如何在C++中专门化 std::vector 的模板模板参数
- 按参数C++类型专门化重载构造函数
- 将“类型参数”与“非类型参数”(或相反)专门化
- 如何在非模板化类中专门化没有参数的模板化方法
- 在 C++ 中鸭子键入(通过其非类型模板参数的值专门化模板函数)
- 使用已推导的模板参数专门化模板成员函数