8

我刚刚意识到尝试通过 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

在 gcc 4.7.3 上。

因此,ADL 在调用函数(输出中的第 1 行)时有效,但在 VS2012 上的 decltype 内使用时无效。

还是我错过了一些不同的观点?

4

2 回答 2

2

一个最小的测试用例是:

namespace N
{
    struct C {};

    C f(C) {};
}

N::C c1;

decltype(f(c1)) c2;

如果编译器在 decltype 中不支持 ADL,则上述内容将无法编译。

有人告诉我它确实可以编译,所以问题可能出在 ADL 和模板实例化之间的交互上。

于 2013-07-16T19:26:20.833 回答
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 类型的变量。这似乎是一个独立于模板的问题。

于 2013-07-16T19:58:54.423 回答