8

Właśnie sobie sprawę, że próby uzyskania typu zwrotu funkcji przez decltype nie obejmuje ADL (wyszukiwanie zależne od argumentu) na VS2012 (testowane przy użyciu cl.exe V17.00.60610.1).Brak ADL wewnątrz decltype na VS2012

Poniższy przykład

#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; 
} 

Daje

B::Func(XX const *) 
Type: int 

na VS2012

ale (co jest spodziewane):

B::Func(XX const *) 
Type: f 

na gcc 4.7.3.

Tak więc funkcja ADL działa podczas wywoływania funkcji (wiersz 1 na wyjściu), ale nie w przypadku użycia wewnątrz typu decltype w VS2012.

A może brakuje mi jakiegoś innego punktu?

+2

VS2012 Obsługa 'decltype' jest dość słaba (szukaj frazy" wyrażenie SFINAE "i płacz), więc nie jestem aż tak zaskoczony. – Yakk

+0

wiele funkcji C++ 11 cechowało się wysoką jakością alpha w VS2012 i późniejszym CTP w listopadzie. Podobno istnieje długa lista naprawionych błędów w podglądzie VS2013 (Express jest obecnie dostępny do pobrania). Możesz tam spróbować szczęścia. – TemplateRex

+0

A co z nowym sposobem częstych aktualizacji w celu rozwiązania błędów i dodania nowych funkcji, których MS chciało przestrzegać od VS2012 ... Więc co ... na szczęście nie jestem ograniczony w wyborze mojego kompilatora w tym konkretnym projekcie, więc wszystkie moje nadzieje i sny są przypięte na VS2013 :-) – mmmmmmmm

Odpowiedz

2

Minimalny przypadek testowy jest:

namespace N 
{ 
    struct C {}; 

    C f(C) {}; 
} 

N::C c1; 

decltype(f(c1)) c2; 

Jeśli kompilator nie obsługuje ADL wewnątrz decltype, to powyższe nie będzie skompilować.

Powiedziano mi, że kompiluje, więc może to interakcja między ADL i instancją szablonów jest problemem.

+0

Jeśli "c1" jest zadeklarowane w przestrzeni nazw 'N :: C c1; i 'c2' jako funkcja (ponieważ MSVS nie zaakceptuje zmiennej typu' void'), kompiluje. – Pixelchemist

+0

@Pixelchemist: Naprawiono, dzięki. Jeśli MSVS je skompiluje, to msvs nie ma problemu z ADL wewnątrz decltype w co najmniej kilku przypadkach. –

2

Jeśli okaże się to zabawne, to IDE/Intellisense wydaje się poprawnie sprawdzać, ale kompilator tego nie robi.

W tym przykładzie brak błędów intellisense i wyświetlenie a na typ size_t po najechaniu nim.

Kompilator zatrzymuje się na Error C2182 i narzeka na zmienną typu void. Wydaje się, że jest to problem niezależny od szablonów.

+0

Program Visual C++ korzysta z innego interfejsu C++ dla funkcji IntelliSense i IDE, więc istnieje wiele subtelnych różnic między tym, co akceptuje IntelliSense, a tym, co akceptuje kompilator. –

+0

Dzięki za informacje. Nie jestem zaskoczony, ale rozbawiony. Chciałem tylko wskazać, że szablony nie stanowią problemu. – Pixelchemist