VS2012上的decltype内没有ADL

时间:2013-07-16 11:01:19

标签: c++ visual-studio-2012 c++11 decltype argument-dependent-lookup

我刚刚意识到尝试通过decltype获取函数的返回类型不涉及VS2012上的ADL(参数依赖查找)(使用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

on gcc 4.7.3。

因此ADL在调用函数时会起作用(输出中的第1行),但在VS2012中的decltype中使用时则不行。

或者我错过了一些不同的观点?

2 个答案:

答案 0 :(得分:2)

最小的测试用例是:

namespace N
{
    struct C {};

    C f(C) {};
}

N::C c1;

decltype(f(c1)) c2;

如果编译器不支持decltype中的ADL,那么上面的代码将无法编译。

我被告知它确实编译了,所以也许是ADL和模板实例化之间的交互就是问题。

答案 1 :(得分: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类型的变量。 这似乎是一个独立于模板的问题。