0

私は、ルックアップおよび過負荷解像度が異なる動作をする場合があります。オーバーロードの解決、名前検索と関数ポインタ

  • ユーザー定義クラスため対ビルトイン STD VSタイプ::文字列
  • 私はこれらのdiffeを正当化し、正確なものを標準の部品把握することはできません

ダイレクトコール関数ポインタ呼び出しの

  • rences。

    use1<float>: 0 
    use1<Test1>: 10 
    use1<int>: 20 
    use1<Test2>: 30 
    use1<string>: 0 
    use1<double>: 0 
    
    use2<float>: 0 
    use2<Test1>: 10 
    use2<int>: 20 
    use2<Test2>: 0 
    use2<string>: 0 
    use2<double>: 0 
    

    質問:

    #include <iostream> 
    #include <string> 
    
    using namespace std; 
    
    struct Test1 {}; 
    struct Test2 {}; 
    
    template<typename T> 
    int f(T t) { return 0; } 
    
    int f(Test1 t) { return 10; } 
    int f(int y) { return 20; } 
    
    template<typename T> 
    int use1() { return f(T()); } 
    
    template<typename T> 
    int use2() { auto fp = static_cast<int(*)(T)>(&f); return (*fp)(T()); } 
    
    int f(Test2 t) { return 30; } 
    int f(string s) { return 40; } 
    int f(double y) { return 50; } 
    
    int main() { 
        cout << "use1<float>: " << use1<float>() << endl; 
        cout << "use1<Test1>: " << use1<Test1>() << endl; 
        cout << "use1<int>: " << use1<int>() << endl; 
        cout << "use1<Test2>: " << use1<Test2>() << endl; 
        cout << "use1<string>: " << use1<string>() << endl; 
        cout << "use1<double>: " << use1<double>() << endl; 
        cout << endl; 
        cout << "use2<float>: " << use2<float>() << endl; 
        cout << "use2<Test1>: " << use2<Test1>() << endl; 
        cout << "use2<int>: " << use2<int>() << endl; 
        cout << "use2<Test2>: " << use2<Test2>() << endl; 
        cout << "use2<string>: " << use2<string>() << endl; 
        cout << "use2<double>: " << use2<double>() << endl; 
        return 0; 
    } 
    

    アウトプット(G ++ 6.3と打ち鳴らす++ 5.0.0トランクと同じ)である:

    は、以下のC++ 11のコードを検討します:

    1. なぜuse1<string>use1<Test2>と異なるのですか?両方の型が "先頭"に宣言され、両方のf()オーバーロードが下側に宣言されます。
    2. なぜuse1<Test2>use1<double>と異なるのですか?対応するf()オーバーロードは隣接する行にありますが、組み込み型の扱いに特別なものはありますか?
    3. なぜuse1<Test2>use2<Test2>と異なるのですか? use2の関数へのポインタの型はuse1の呼び出しコンテキストと一致しているようです。
  • 答えて

    0

    2フェーズの名前検索。 use1が定義されている時点で、通常のルックアップを使用してfの3つのオーバーロードが表示されます。インスタンス化の時点で、追加のオーバーロードが検出される可能性がありますが、引数依存のルックアップによってのみ検出されます。 Test2はグローバルネームスペースにあるため、f(Test2)がADLによって見つかります。 stringはネームスペースstdにありますので、f(string)(明らかにネームスペースstdにはありません)がADLによって見つかりません。 doubleには名前空間が関連付けられていないため、ADLはまったく失敗しません。

    use2では、fは従属名ではないため、第2段階のルックアップはまったく実行されません。定義時点で表示されるオーバーロードのみが考慮されます。

    +0

    ありがとうございました! use2に関して:use1で解決されたf()の全く同じオーバーロードのアドレスを含む関数ポインタを得るために、use2にの方法がありますか?? – salmin

    +0

    私は名前を「依存させる」方法は考えられません。標準では、ストレート関数呼び出しで名前が使用されたときは第2ルックアップフェーズ、名前(some_args)のみが想定され、過負荷解決が必要な場合は想定されていません。 –

    関連する問題