1

私は新しいコンテナを作成しており、次のようN3485 23.2.3 [sequence.reqmts]/14に記載されている に準拠しようとしています:

この条項および条項 21 で定義されているすべてのシーケンス コンテナーについて:

  • コンストラクターの場合

    template <class InputIterator>
    X(InputIterator first, InputIterator last, 
         const allocator_type& alloc = allocator_type())
    

    InputIteratorが入力反復子として修飾されない型で呼び出された場合、コンストラクターはオーバーロードの解決に参加しません。

(/14イテレータ範囲を取るメンバー関数について、これをほぼそのまま繰り返します)

N3485 23.2.3 [sequence.reqmts]/15言います:

実装が型を入力反復子にできないと判断する程度は規定されていません。

私の理解では、「オーバーロードの解決に参加しない」というフレーズは、コンテナーの実装者が SFINAE トリックを使用して、テンプレート引数の推定中にそのコンストラクターまたはメンバー関数を無効にすることになっていることを意味します。メンバー関数の場合、これは大したことではありません。関数の戻り値の型は通常の使用方法enable_ifです。ただし、コンストラクターの場合、enable_if適用できる戻り値の型はありません。これは、コンストラクターを宣言する最初の試みでした。

// The enable_if use below is to comply with 23.2.3 [sequence.reqmts]/14:
//     ... is called with a type InputIterator that does not qualify as an input iterator
//     then the constructor shall not participate in overload resolution.
template <typename InputIterator>
path(std::enable_if<!std::is_integral<InputIterator>::value, InputIterator>::type first,
     InputIterator last, Allocator const& allocator = allocator_type());

ただし、boost のenable_ifドキュメントnullptrでは、関数に実際のパラメーターを使用する代わりに、初期化されたダミー ポインター パラメーターを使用することを提案しています。ここで正しい動作をするために必要ですか、それともpathのイテレータ範囲コンストラクタの前の宣言は大丈夫ですか?

4

1 に答える 1

3

The Good Robot (R. Martinho Fernandes) は、クリーンな C++11 ソリューション、つまりデフォルトのテンプレート パラメーターを使用して apply を使用する問題について、enable_ifのブログで説明しています。

ただし、ここで指摘させてください。

    template< class Type >
    void foo( typename Something< Type >::T )

はく引数控除

テンプレート引数を明示的に指定することで、関数を呼び出すことは引き続き可能です。MyTypeしかし、C++ では、コンパイラは、たとえば実引数を仮引数 typeに一致させることを単純に拒否しSomething<Blah>::Tます。これは、特殊なケースでは実行できますが、常に実行できるとは限らないためです ( Blahwhere Something<Blah>::Twasの無数の選択肢がある可能性がありますMyType)。

したがって、現在のアプローチは一般的には機能しませんが、仕様の要件の問題全体は C++11 の問題であるため、C++11 固有のソリューションは問題ありません! :-)

于 2012-12-09T22:30:03.437 に答える