1

本「Accelerated C++」(A. Koenig、B. Moo) (§8.2.2) からいくつかのサンプル コードを実行しようとしています。

#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

template <class In, class X>
In find(In begin, In end, const X &x)
{
    while (begin != end && *begin != x) {
        ++begin;
    }

    return begin;
}

int main()
{
    vector<int> v;

    v.push_back(5);
    v.push_back(32);
    v.push_back(42);
    v.push_back(7);

    cout << *find(v.begin(), v.end(), 42) << endl;

    return 0;
}

find関数は本では次のように表示されます。main自分で書いた関数。

clang++ と g++ の両方がこれをコンパイルしません。find私の関数が とあいまいさを導入したと彼らが不平を言っているようstd::findです。ただし、コード内で使用したことはありませusing namespace::std;ん。何が起きてる?using std::find;std::find

4

1 に答える 1

4

「Koenig ルックアップ」(はい、同じ Koenig であるため、彼が問題を発見すると思うでしょう)、別名「ADL」につまずいたと思います。

少しの間、間接インクルードを介し<algorithm>て引き込まれたとします。

std::vector<int>::iterator(引数の型) が namespace のクラスである場合std、それstd::findを「使用」したことがなくても呼び出しに一致するため、呼び出しはあいまいです。

が の場合、std::vector<int>::iteratorは候補ではなく、呼び出しはあいまいではありません。int*std::find

どちらの方法も の有効な実装であり、 orが を含むstd::vectorかどうかにかかわらず、実装定義でもあります。したがって、コードは移植可能ではありませんが、コードが実際にその実装で失敗しない限り、実装は移植性の問題を診断することがほとんどできません。<iostream><vector><algorithm>

ADL のより一般的なケースでは、関連付けられた名前空間の関数または関数テンプレートは、呼び出し元が存在または "使用" する名前空間の関数または関数テンプレートよりも適切な (より具体的な) 候補であるため、あいまいさが回避されます。ただし、グローバルfindは基本的に と同じstd::findであるため、適用されません。

http://ideone.com/Cskur :

#include <iostream>

namespace foo {
    struct Foo {};

    /* same as the one we'll define later */
    template <typename T>
    void func(T) {
        std::cout << "namespace function template\n";
    }
    /* this would be a better match
    void func(Foo) {
        std::cout << "namespace function\n";
    }
    */
}

template <typename T>
void func(T) {
    std::cout << "global function template\n";
}

int main() {
    foo::Foo f;
    func(f);
}

結果:

prog.cpp:19: error: call of overloaded ‘func(foo::Foo&)’ is ambiguous

std結論: の名前を使用することは、他の名前空間であっても多少危険です。

または、必要に応じて、他の名前空間から名前を定義stdすると、呼び出し元が注意する必要があることを意味する場合があります。違いは、バグが発生したときに誰がバグを修正するかという問題です。

于 2012-05-31T00:05:59.463 に答える