【问题标题】:No ADL inside decltype on VS2012VS2012 上的 decltype 内没有 ADL
【发布时间】:2013-07-16 11:01:19
【问题描述】:

我刚刚意识到尝试通过 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 中使用时无效。

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

【问题讨论】:

  • VS2012 decltype 支持很差(搜索“表达式 SFINAE”并哭泣),所以我并不感到惊讶。
  • 许多 C++11 特性在 VS2012 和随后的 11 月 CTP 中非常具有 alpha 质量。据说在 VS2013 预览版中有一长串已修复的错误(Express 目前可供下载)。你可以在那里碰碰运气。
  • 那么,自 VS2012 以来,非常频繁的更新以解决错误并添加 MS 想要遵循的新功能的新方法呢...那么呢...幸运的是,我的编译器选择不受限制这个特定的项目,所以我所有的希望和梦想都寄托在 VS2013 上:-)

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


【解决方案1】:

一个最小的测试用例是:

namespace N
{
    struct C {};

    C f(C) {};
}

N::C c1;

decltype(f(c1)) c2;

如果编译器不支持decltype里面的ADL,那么上面的就不会编译了。

我听说它确实可以编译,所以问题可能是 ADL 和模板实例化之间的交互。

【讨论】:

  • 如果 c1 使用命名空间 N::C c1; and c2` 作为函数声明(因为 MSVS 不接受 void 类型的变量),它会编译。
  • @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 类型的变量。 这似乎是一个独立于模板的问题。

【讨论】:

  • Visual C++ 对 IntelliSense 和 IDE 功能使用不同的 C++ 前端,因此 IntelliSense 接受的内容与编译器接受的内容之间存在许多细微差别。
  • 感谢您的信息。我不是很惊讶,而是很开心。我只是想提示模板不是这里的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多