8

decltype を介して関数の戻り値の型を取得しようとすると、VS2012 で ADL (argument-dependent-lookup) が含まれないことに気付きました (cl.exe V17.00.60610.1 を使用してテスト)。

次の例

#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;
}

与える

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

VS2012で

しかし(予想されること):

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

gcc 4.7.3 で。

そのため、ADL は関数 (出力の 1 行目) を呼び出すときに機能しますが、VS2012 の decltype 内で使用すると機能しません。

それとも、別のポイントがありませんか?

4

2 に答える 2

2

IDE/Intellisense はルックアップを正しく行っているように見えますが、コンパイラはそうではありません。

この例では、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 の変数について不平を言います。テンプレートに依存しない問題のようです。

于 2013-07-16T19:58:54.423 に答える