请考虑以下代码,该代码使用"模板模板"参数来使用多种类型实例化类模板:
#include <iostream>
using namespace std;
enum E
{
a = 0,
b = 1
};
template <template <E> class Action, class T>
void do_something(const T& value)
{
typedef Action<a> type1;
typedef Action<b> type2;
}
template <E e, class Enable = void>
class Foo
{
};
int main()
{
do_something<Foo>(int(55));
}
Run Code Online (Sandbox Code Playgroud)
使用较旧的编译器(GCC 4.1.2),上面的代码编译得很好.但是,使用较新的编译器(GCC 4.4.6或4.8.1),会产生以下错误:
test3.cpp:25:27: error: no matching function for call to ‘do_something(int)’
do_something<Foo>(int(55));
Run Code Online (Sandbox Code Playgroud)
所以它看起来像GCC无法绑定do_something,因为模板模板参数只声明一个参数(一个枚举),但是Foo实际上需要两个模板参数(即使一个是默认值.)我猜GCC 4.1.2允许默认参数被忽略.
好的,如果我将模板定义更改为:
template <template <E, class> class Action, class T>
void do_something(const T& value)
{
typedef Action<a> type1;
typedef Action<b> type2;
}
Run Code Online (Sandbox Code Playgroud)
...那么我测试的GCC版本都没有编译它.它们都会产生类似的错误:
test3.cpp:13: error: wrong number of template arguments (1, should be 2)
test3.cpp:10: error: provided for ‘template<E <anonymous>, class> class Action’
Run Code Online (Sandbox Code Playgroud)
所以现在,编译器抱怨因为表达式typedef Action<a> type1只提供单个模板参数.显然,我无法隐式使用默认参数.
有什么方法可以在模板模板函数中使用模板的默认参数吗?
模板参数的参数将忽略默认参数.在n3337,章节[temp.arg.template],第2段中有这个例子:
template<class T> class A { /? ... ?/ };
template<class T, class U = T> class B { /? ... ?/ };
template <class ... Types> class C { /? ... ?/ };
template<template<class> class P> class X { /? ... ?/ };
template<template<class ...> class Q> class Y { /? ... ?/ };
X<A> xa; // OK
X<B> xb; // ill-formed: default arguments for the parameters of a template argument are ignored
X<C> xc; // ill-formed: a template parameter pack does not match a template parameter
Y<A> ya; // OK
Y<B> yb; // OK
Y<C> yc; // OK
Run Code Online (Sandbox Code Playgroud)
请注意X<B> xb;上面的评论.我害怕,我找不到规范性文字.
您可以将其与函数关联 - 默认参数也不是签名的一部分.如果您尝试通过函数指针调用具有参数默认值的函数,也会发生同样的事情.
| 归档时间: |
|
| 查看次数: |
1432 次 |
| 最近记录: |