2017-04-19 3 views
8

私のコードがコンパイルされず、C++でそれを実現した理由を実証しようとしました引数依存型参照はテンプレートのtypename名前検索範囲を決定するための引数。型がクラステンプレートの特殊化である引数のADLの背後にあるもの

#include <string> 
#include <functional> 

namespace myns { 

    template<typename T> 
    struct X 
    {}; 

    template<typename T> 
    auto ref(T) -> void 
    {} 

} // namespace myns 

auto main() -> int 
{ 
    ref(myns::X<int>{}); 
    ref(myns::X<std::string>{}); // error: call to 'ref' is ambiguous 
} 

だから、かつてのREFコールコンパイル、後者はコンパイルされませんが、それはmyns::ref()などstd::ref

私の質問はこれがいかにで見つけたのでmyns::X<int>のみmyns::refが、考えられているので、有用?なぜ私はこれが必要でしょうか?アイデアや例がありますか?今のところ私は上記の例のような不具合を見るしかありませんが、不必要なあいまいさがあります。

+0

*任意の*タイプを受け入れる機能が必要ですか?それ以外の場合、 'auto ref(X ) - > void'は' std :: ref'よりも良い一致となり、過負荷解決によって選択されます。 –

+0

残念ながらはい、私はします。 – witosx

答えて

7

ユーザ定義のクラスや、std::vectorをパラメータとする関数など、すべてのものを自分の名前空間に入れるとします。すなわち

namespace myns { 

    struct X {}; 

    template<typename T> 
    auto my_func(const std::vector<T>&) -> void 
    {} 

} // namespace myns 

あなたはADLもテンプレート引数として提供さ種類を考慮し、ちょうど書くという事実を利用することができます。一方

my_func(std::vector<myns::X>{}); 

my_func(std::vector<int>{});  // error, can't find my_func 
myns::my_func(std::vector<int>{}); // fine 

元の質問に戻りましょう。ここでの教訓は、標準ライブラリの名前を使用しないことですコードを混乱させるだけです。

3

一言で言えば、再使用。これにより、他のライブラリの有用なコンポーネントを使用して、ADLを適用することができます。例えば

:あなたが直接クラスで作業する場合と同様に

namespace my_stuff { 
    class my_class { 
    // Something useful here 
    }; 

    void process(std::unique_ptr<my_class> item); 
} 

今、あなたは、自然にコードを書くことができます。

process(std::make_unique<my_class>()); 

それはそうではなかった場合は、必要があると思い独自の名前空間で自分のスマートなポインタを展開して、良いコーディングイディオムとADLを容易にすることができます。

関連する問題