12

C++03 では、一部のコンテキストでテンプレート パラメーターの推定が行われません。例えば:

template <typename T> struct B {};

template <typename T>
struct A
{
    typedef B<T> type;
};

template <typename T>
void f(typename A<T>::type);

int main()
{
    B<int> b;
    f(b);  // ERROR: no match
}

ここでは、 のような入れ子になった型は推定されないコンテキストであるため、intは推定されません。TA<T>::type

私はこのように関数を書いていました:

template <typename T> struct B {};

template <typename T>
void f(B<T>);

int main()
{
    B<int> b;
    f(b);
}

推論されたコンテキストであるB<T> ため、すべて問題ありません。

ただし、C++11 では、テンプレート エイリアスを使用して、2 番目の例のような構文でネストされた型を偽装できます。例えば:

template <typename T> struct B {};

template <typename T>
struct A
{
    typedef B<T> type;
};

template <typename T>
using C = typename A<T>::type;

template <typename T>
void f(C<T>);

int main()
{
    B<int> b;
    f(b);
}

この場合、テンプレート引数の推論は機能しますか? 言い換えれば、テンプレートエイリアスは推定されたコンテキストですか、それとも推定されていないコンテキストですか? それとも、エイリアスの推定/非推定ステータスを継承しますか?

4

3 に答える 3

10

言い換えると、テンプレートエイリアスは推定コンテキストですか、それとも非推定コンテキストですか?

これらは、テンプレートエイリアスを使用せずに、同等のコードと同じように推論できます。例えば

template<typename T>
using ref = T&;

template<typename T>
void f(ref<T> r);

今、あなたは電話f(x)Tすることができ、完全にうまく推論されます。の定義時にfref<T>はタイプに置き換えられT&ます。そしてT&、推測されたコンテキストです。

あなたの場合C<T>は、に置き換えられます。これtypename A<T>::typeは、の非推定コンテキストであるためTT推定できません。

于 2012-01-08T10:49:55.040 に答える
2

これを想像してください:

template <typename T> struct Foo { typedef   T type; }
template <> struct Foo<char>     { typedef int type; }

template <typename T> using mytype = typename Foo<T>::type;

template <typename T> void f(mytype<T>);

もし私が望むなら、私が望むint n; f(n);かどうかをどのように決めることができますT = intT = char?テンプレート エイリアスの影響を受けない全体的な問題は、何かを定義する可能性のあるすべてのものを逆方向に推測できないことです。

于 2012-01-08T03:48:52.927 に答える
1

C++ 標準の関連する引用は 14.5.7 [temp.alias] パラグラフ 2 だと思います。

template-id がエイリアス テンプレートの特殊化を参照する場合、エイリアス テンプレートの type-id の template-parameters を template-arguments に置き換えることによって取得される関連する型と同等です。[ 注: エイリアス テンプレート名は決して推測されません。— エンドノート]

関数テンプレートでエイリアステンプレートを使用することは無意味であり、テンプレート引数を推測することを望んでいることを効果的に綴る引用に続く例があります。これは、ネストされた型を含まない状況でも明らかに適用されます。

于 2012-01-08T04:04:18.600 に答える