2012-08-29 12 views
12

関数オブジェクトは、オーバーロード解決時に通常の関数とは異なる扱いをしていますか?もしそうなら、どうですか?関数オブジェクトは過負荷解決にどのように影響しますか?

私は同等に呼び出し可能な関数オブジェクトと機能を交換するには、コードの意味を変更し、次の場合に実行した:

#include <iostream> 

namespace N 
{ 
    enum E { A, B }; 

    void bar(E mode) { std::cout << "N::bar\n"; } 
} 

template <typename... Args> 
void bar(Args&&... args) { std::cout << "global bar\n"; } 

int main() 
{ 
    bar(N::A); 
} 

ここで出力が「N ::バー」です。これまでのところ、N :: barはADLによって検出されています。N :: barとグローバルバーは完全に一致しています。テンプレートではないため、N :: barが優先されます。

しかし、私はそうのように、関数オブジェクトであることを世界的なバーを変更した場合:

#include <iostream> 

namespace N 
{ 
    enum E { A, B }; 

    void bar(E mode) { std::cout << "N::bar\n"; } 
} 

struct S 
{ 
    template <typename... Args> 
    void operator()(Args&&... args) { std::cout << "global bar\n"; } 
}; 
S bar; 

int main() 
{ 
    bar(N::A); 
} 

出力は今や「世界のバー」です。なぜ違い?

答えて

12

ここで重要なのは、ルックアップで名前であると判断した場合、ADLが起動するということです。第2のケースでは、barオブジェクトであり、関数ではないので、式bar(N::A)は関数呼び出しではなく、オブジェクトbarへのoperator()の適用です。それは関数呼び出しではないので、ADLはキックインされず、N::barは考慮されません。

3.4.1/3

3.4.2に記載されている関数呼び出しの後置表現として使用される非修飾名のルックアップ。 [注意:式がファンクションコールの後置式であるかどうかを(解析中に)決定するために、通常の名前検索規則が適用されます。 3.4.2 [ADL]の規則は、式の構文的解釈に影響しません。それを見て

もう一つの方法は、ADLがオーバーロード関数のセットに新しい機能が追加されますが、2番目の例では、そのようなセットが存在しないことに気づくことです:ルックアップは、オブジェクトのメンバーを見つけますオブジェクトが呼び出されます。

+2

今日、私はDavidに感謝しました。 – ildjarn

+0

私は3.4でノートがないと思います。'bar' *は関数呼び出し式の後置式である(オペランドとしての機能を持たず、最終的には1つを呼び出す!)ため、1/3が関係します。 3.4.2は、 "x(y)"の構文上の意味を変更しないことに注意してください。関数呼び出しの場合、3.4.2で決める関数の呼び出しを無視しています。 –

+0

@ JohannesSchaub-litb:通常の検索では、 'bar'はオブジェクトであり、オブジェクトである' bar(x) 'はそのインスタンスへの' operator() 'のアプリケーションを表します。演算子のアプリケーションは関数呼び出しですが、* member-function *呼び出しであるため、ADLは適用されません。 –

4

は(3.4.1)Xは、非修飾参照によって生成ルックアップ集合とすると、Yは、(次のように定義される)は、引数依存の検索によって生成ルックアップセットすることができます。と言う3.4.2p3を参照してください。 Xは

  • ...
  • 関数または関数テンプレートでもない宣言が含まれている場合

は、Yは空です。

このようなルールがない場合は、正しくあります.ADLは、他の機能をオーバーロードセットに追加します。実際、13.3.1.1p1はこれに依存しています。 1つはオペランドがクラスオブジェクトを示す関数呼び出し式用であり、もう1つはオペランドが1つ以上の関数または関数テンプレートを示すものである。

+0

+1、標準のその部分を見直した後、あなたが提供する見積もりが、私が引用した注釈の理由です。 –

+0

@davidあなたはそれを誤解しています –

関連する問題