1

テンプレートを使用せずにADLの例を見せてもらえますか?そのようなものを見たことがない。私はここのようなものを意味します。具体的には、前述のような落とし穴につながる例に興味があります。

編集:

Tomalakの答えは落とし穴にまで拡張できると思います。このことを考慮:

namespace dupa {

    class A {
    };

    class B : public A {
    public:
        int c;
        B() {
        }
    };

   void f(B b) {
       printf("f from dupa called\n");
   }
}

void f(dupa::A) {
    printf("f from unnamed namespace called\n");
}


int main()
{   
    dupa::B b;
    f(b);

    return 0;
}

ここでは、名前のない名前空間からfが呼び出されることを期待していますが、代わりに別の名前空間が呼び出されます。

4

3 に答える 3

4

落とし穴につながる何かをお見せすることはできませんが、テンプレートなしでADLが機能することを示すことはできます。

namespace foo {
   struct T {} lol;
   void f(T) {}
}

int main() {
   f(foo::lol);
}

lolのタイプはclass-type;でなければならないことに注意してください。ご覧のとおり、もともとビルトインで試してみましたが、うまくいきませんでした。

于 2011-07-13T21:05:56.557 に答える
2

混乱を招く秘訣は、関数の引数が交換可能または変換可能であり、ADLが期待したものとは異なるものを選択する可能性があるシナリオを作成することです。これが印象的なのか、それとも期待されているのかわかりません:

namespace a {
   struct A {};
   void f( A* ) { std::cout << "a::f" << std::endl; }
}
namespace b {
   struct B : ::a::A {};
   void f( B* ) { std::cout << "b::f" << std::endl; }
}

void test() {
   f( new b::B );     // b::f
   a::A* p = new b::B; 
   f( p );            // a::f
}

タイプは同じですが、ADLは引数の静的タイプをチェックし、その名前空間を検索に追加します。つまり、正確な静的型によって、コンパイラーにさまざまな関数が表示される可能性があります。ADLまたは過負荷解決を適用できる引数が複数ある場合は、事態がさら​​に混乱する可能性があります。

于 2011-07-13T21:40:41.133 に答える
2

テンプレートはありません。
それが最も一般的な使用法であるため、swap()を使用します。

#include <iostream>

namespace One
{
    class A {};
    void swap(A& lhs, A& rhs) { std::cout << "Swap-One A\n";}
}

namespace Two
{
    class A {};
    void swap(A& lhs, A& rhs) { std::cout << "Swap-Two A\n";}
}


int main()
{
    One::A      oneA_l;
    One::A      oneA_r;
    Two::A      twoA_l;
    Two::A      twoA_r;

    swap(oneA_l, oneA_r);
    swap(twoA_l, twoA_r);
}
于 2011-07-13T21:58:53.557 に答える