I just realized that trying to get the return type of a function via decltype does not involve ADL (argument-dependent-lookup) on VS2012 (tested using cl.exe V17.00.60610.1).
The following example
#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;
}
Gives
B::Func(XX const *)
Type: int
on VS2012
but (what is expected):
B::Func(XX const *)
Type: f
on gcc 4.7.3.
So ADL works when calling the function (line 1 in output) but not when used inside decltype on VS2012.
Or am I missing some different point?
A minimal test case is:
namespace N
{
struct C {};
C f(C) {};
}
N::C c1;
decltype(f(c1)) c2;
If the compiler doesn't support ADL inside decltype, then the above will not compile.
I'm told it does compile, so maybe it is the interaction between ADL and template instantiation that is the problem.
If find it amusing that the IDE/Intellisense whatsoever seems to do the lookup correctly but the compiler does not.
This example shows no intellisense errors and a
is displayed to be of type size_t
when hovering it.
#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);
}
The compiler stops with Error C2182
and complains about a variable of type void.
It seems to be a problem independant of templates.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With