我刚刚意识到尝试通过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
但是(预期的是):
B::Func(XX const *)
Type: f
on gcc 4.7.3。
因此ADL在调用函数时会起作用(输出中的第1行),但在VS2012中的decltype中使用时则不行。
或者我错过了一些不同的观点?
答案 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类型的变量。
这似乎是一个独立于模板的问题。