1

これが C++ で機能しないのはなぜですか? のパラメータをこのよう
に制限できないのはなぜですか? また、最善の回避策は何ですか?foostd::vector<T>::iterator

#include <vector>

template<class T>
void foo(typename std::vector<T>::iterator) { }

int main()
{
    std::vector<int> v;
    foo(v.end());
}

エラーは次のとおりです。

In function ‘int main()’:
     error: no matching function for call to ‘foo(std::vector<int>::iterator)’
     note: candidate is:
    note: template<class T> void foo(typename std::vector<T>::iterator)
    note:   template argument deduction/substitution failed:
     note:   couldn’t deduce template parameter ‘T’
4

2 に答える 2

6

それが機能しない主な理由は、サンダードが、Tここは推論されていないコンテキストにあると言っているためです。コンテキストが推定されない理由は、関数に何らかの型を渡すと、コンパイラは可能なすべてのインスタンスを作成する必要があるstd::vectorためです (この特定の翻訳単位に存在しない型を含む)。対応するタイプ。

もちろん、 の場合std::vector、クラスのセマンティクスは標準で定義されているため、コンパイラにはこれを機能させるための魔法が含まれている可能性があります。しかし、一般的に TemplateClass<T>::NestedTypeは、文字通り何に対しても typedef になる可能性があり、コンパイラがそれに対してできることは何もありません。

于 2013-03-04T18:47:37.580 に答える
2

単純。

struct X {};
template<> class std::vector<X> {
    typedef std::vector<int>::iterator iterator;
};

おっとっと。

テンプレートはチューリング完全です。結果から引数を推測するようにコンパイラに要求しています。これは、非 1 対 1 対応の可能性を無視しても、一般的なケースでは不可能です。

通常、反復子の型自体をテンプレート パラメーターとして使用します。これにより、deque、循環バッファーなどの他のランダムアクセス反復子が許可されます。

于 2013-03-04T18:42:11.623 に答える