4

「テンプレート テンプレート」パラメーターを使用して、複数の型を使用してクラス テンプレートをインスタンス化する次のコードを検討してください。

#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));
}

古いコンパイラ (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));

したがって、GCC は にバインドできないように見えdo_somethingます。テンプレート テンプレート パラメーターは 1 つのパラメーター (Enum) しか宣言しないため、Foo実際には 2 つのテンプレート パラメーターを使用します (1 つは既定値ですが)。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;
}

...そして、私がテストした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’

typedef Action<a> type1そのため、式が 1 つのテンプレート パラメーターしか提供しないため、コンパイラは文句を言います。どうやら、ここでデフォルトのパラメーターを暗黙的に使用することはできません。

テンプレート テンプレート関数でテンプレートの既定のパラメーターを使用する方法はありますか?

4

2 に答える 2

6

テンプレート引数のパラメータでは、デフォルトの引数は無視されます。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

上記のコメントに注意してくださいX<B> xb;。残念ながら、規範的なテキストが見つかりません。

これを関数と関連付けることができます。デフォルトの引数も署名の一部ではありません。関数ポインターを介してデフォルト設定されたパラメーターを持つ関数を呼び出そうとした場合にも、同じことが起こります。

于 2013-10-15T20:30:28.893 に答える