Нет ADL внутри decltype на VS2012

Я только что понял, что попытка получить возвращаемый тип функции через decltype не включает ADL (аргумент-зависимый поиск) на VS2012 (протестировано с использованием 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 на выходе), но не при использовании внутри decltype на VS2012.

Или я упускаю какую-то другую точку?

8

Решение

Минимальный тестовый пример:

namespace N
{
struct C {};

C f(C) {};
}

N::C c1;

decltype(f(c1)) c2;

Если компилятор не поддерживает ADL внутри decltype, то вышеописанное не скомпилируется.

Мне сказали, что он компилируется, поэтому, возможно, проблема заключается в взаимодействии между ADL и созданием шаблона.

2

Другие решения

Если вы находите забавным то, что IDE / Intellisense, кажется, выполняет поиск правильно, а компилятор — нет.

Этот пример не показывает ошибок 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.
Кажется, проблема не зависит от шаблонов.

2