3

タイプがある場合T、コンパイル時にそれを検査して、そのSTLスタイルのコンテナー(任意の値タイプの場合)かどうかを確認するための便利な方法は何ですか?
(仮定:ポインター、参照などはすでに削除されています)

開始コード:

template<class T> // (1)
void f(T&) {} 

template<class T> // (2)
void f(std::vector<T>&) {} 

void test() 
{
    int a;
    std::vector<int> b;
    f(a);
    f(b);
}

これで問題なく動作しますが、コンテナを一般化したい場合(つまり、(3)(4)、...を明示的に定義しない場合)はどうなりますか?

SFINAEとタイプリストを利用すると、コードがいくらか削減されますが、より良い方法はありますか?
それとも、概念に基づいて専門化するためのイディオムはありますか?
または、どういうわけかSFINAEを利用して、目的の専門分野のみを選択的に有効にすることはできますか?

補足として、私はイテレータを使用できません-Tパラメータとしてsを受け取る関数に基づいて専門化しようとしています。


MSaltersの答えによると

template<class T>
void f(T&, ...) {
    std::cout << "flat" << std::endl; 
}

template<class Cont>
void f(Cont& c, typename Cont::iterator begin = Cont().begin(),
                typename Cont::iterator end   = Cont().end()) {
    std::cout << "container" << std::endl; 
}

(可変引数リストは、fあいまいさのエラーを解決するための最初の最も好ましくないバージョンを作成するために必要です)

4

3 に答える 3

2

あなたがすることは、ほとんど確実に非常に壊れやすいものです。「STL」であるかどうかの間に明確な境界線はありません。明確な境界線があったとしても、それはいずれにせよそのような決定の本当に貧弱な根拠になるでしょう。たとえば、より一般的なRBツリーの代わりにAVLツリーを使用するstd :: mapの再実装を作成(または使用)する場合、なぜstd :: mapとは異なる方法で処理する必要があるのでしょうか?

ハッシュ化されたコンテナーの場合、hash_mapのさまざまな実装から、Boostコンテナー、TR1コンテナー、C++0xの標準ライブラリーに含まれるものへと全体的に進歩しています。「STL」の定義方法によっては、そのうちの少なくとも1つがSTLでなく、もう1つがSTLである可能性がかなりありますが、あるものを別のものとは異なる方法で扱うことが理にかなっているポイントはありません。

容器の特性を考えて、自分にとって本当に重要な特性を特定してみるべきだと思います。

于 2009-12-15T03:07:59.767 に答える
2

STLcontainerには、定義上、typedefiteratorがあり、2つのメソッドがbegin()あり、end()それらを再ルーティングします。この範囲、コンテナに含まれる範囲です。そのような範囲がない場合、それはSTLの意味でのコンテナーではありません。だから私は(チェックされていない)の線に沿って何かを推測します

template<typename CONTAINER>
void f(CONTAINER& c,
       typename CONTAINER::iterator begin = c.begin(),
       typename CONTAINER::iterator end = c.end())
{ }
于 2009-12-15T10:51:12.207 に答える
0

www.cplusplus.comによると、すべてのSTLコンテナに共通する機能は次のとおりです。

  • コンストラクター
  • operator=
  • size

コンパイル時に、これらの演算子がタイプに存在するかどうかを判断できますT

于 2009-12-15T02:44:51.233 に答える