8

decltypeで関数の戻り値型を取得しようとすると、VS2012(cl.exe V17.00.60610.1を使用してテスト済み)にADL(引数依存ルックアップ)が含まれません。VS2012のdecltype内にADLがありません

次の例

#include <stdio.h> 
#include <typeinfo> 

namespace A { 
    int Func(void const *) { 
    printf("A::Func(void const *)\n"); 
    return 0; 
    } 

    template <typename T> void Do(T const &t) { 
    Func(&t); 
    } 
    template <typename T> void PrintType(T const &t) { 
    printf("Type: %s\n", typeid(decltype(Func(&t))).name()); 
    } 
} 

namespace B { 
    struct XX { }; 
    float Func(XX const *) { 
    printf("B::Func(XX const *)\n"); 
    return 0.0f; 
    } 
} 


int main(int argc, char **argv) { 
    B::XX xx; 
    A::Do(xx); 
    A::PrintType(xx); 
    return 0; 
} 

が(予想されるもの)VS2012

B::Func(XX const *) 
Type: int 

を与えるが:GCC 4.7.3に

B::Func(XX const *) 
Type: f 

を。

したがって、ADLは関数を呼び出すときに機能しますが(出力の1行目)、VS2012のdecltypeの中で使用されているときは機能しません。

また、いくつかの相違点がありますか?

+2

VS2012 'decltype'のサポートはかなり悪いです(" expression SFINAE "を検索して泣く)ので、私はそれほど驚いていません。 – Yakk

+0

多くのC++ 11の機能は、VS2012とそれに続く11月のCTPでアルファ品質の大部分を占めていました。おそらく、VS2013のプレビュー(現在ダウンロード可能なExpress)で修正されたバグのリストが長いと思われます。あなたはあなたの運を試すかもしれません。 – TemplateRex

+0

VS2012以来、バグを解決し、MSが従っていきたい新しい機能を追加するための非常に頻繁な更新の新しい方法は...だから...幸い私はこの特定のプロジェクトのコンパイラの選択に制限されていないので、夢はVS2013に固定されています:-) – mmmmmmmm

答えて

2

最小限のテストケースは、次のとおり

namespace N 
{ 
    struct C {}; 

    C f(C) {}; 
} 

N::C c1; 

decltype(f(c1)) c2; 

コンパイラはdecltype内部ADLをサポートしていない場合には、上記のコンパイルされません。

私はそれがコンパイルされていると言われているので、ADLとテンプレートのインスタンス化の間のやり取りが問題であるかもしれません。

+0

'c1'が' N :: C c1; 'c2'を関数として(MSVSは' void'型の変数を受け付けないので)コンパイルします。 – Pixelchemist

+0

@Pixelchemist:固定、ありがとう。 MSVSがコンパイルした場合、msvsは少なくともいくつかのケースではdecltype内のADLに問題はありません。 –

2

IDE/Intellisenseがルックアップを正しく実行しているように見えるのは面白いが、コンパイラは正しく表示されない場合は、

この例では、インテリセンスエラーは表示されず、aは、ホバーするとsize_tと表示されます。

#include <iostream> 
namespace A 
{ 
    struct C {}; 
    size_t f(C*) { return 5U; }; 
} 
namespace B 
{ 
    void f(void *) { }; 
    void f2 (A::C x) 
    { decltype(f(&x)) a; std::cout << typeid(a).name() << std::endl; } 
} 

int main (void) 
{ 
    A::C c; 
    B::f2(c); 
} 

コンパイラはError C2182で終了し、void型の変数について不平を言います。 これはテンプレートに依存しない問題です。

+0

Visual C++では、IntelliSenseとIDEの機能に異なるC++フロントエンドを使用しているため、IntelliSenseが受け入れる機能とコンパイラが受け入れる機能との間には、多くの微妙な違いがあります。 –

+0

情報ありがとうございます。私は驚くことではありませんが、面白いです。私はちょうどテンプレートがここで問題ではないというヒントを伝えたいと思っていました。 – Pixelchemist

関連する問題