2012-12-05 14 views
7

W przypadku niepowodzenia zastępowania z użyciem aliasu szablonu (, np. alias szablonu na brakującym pliku nazwa_pliku, jak w poniższym fragmencie kodu), w przypadku wystąpienia błędu?aliasy szablonów i sfinae

Clang i gcc wydają się nie zgodzić na to:

// some types 
struct bar { }; 

struct foo { 
    typedef void member_type; 
}; 


// template alias 
template<class T> 
using member = typename T::member_type; 


template<class T> 
void baz(...) { } 

// only works for gcc, clang fails with: no type named 'member_type' 
// in 'bar' 
template<class T> 
void baz(member<T>*) { } 


int main(int, char**) { 

    baz<bar>(0);   // picks first 
    baz<foo>(0);   // picks second 

    return 0; 
} 

Więc pytanie brzmi: kto jest poprawna i dlaczego?

Dzięki :-)

+0

Co mówi 'clang -v'? Clang 3.3 trunk kompiluje kod dobrze. – Xeo

+0

Wygląd strony Debian w wersji 3.1-8, wygląda na to, że muszę tylko poczekać. Dziekuję za odpowiedź ! – max

+0

Czy możesz pozbyć się aliasu szablonu, aby uprościć trochę sprawy? – David

Odpowiedz

4

według standardów, to wyraźnie GCC, że jest poprawne, ponieważ szablon alias należy natychmiast wymienić, a potem normalne/zwykle SFINAE nakłada się typename T::member_type później kiedy T jest znana.

Ale obecnie istnieje problem, zobacz http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554.

Zgodnie z wynikami spotkań, wydaje się, że pożądane jest zachowanie clangs: Podstawienie T będą wykonywane w kontekście szablonu alias (choć w momencie zastąpienia typename T::member_type, nie ma odniesienie do aliasu szablon już będzie - trzeba będzie odwoływać się do źródła, skąd wziął się wzorzec typu parametru, jeśli tak jest zaimplementowany).


ta jest podobna do innej sytuacji, w której wzory są wyrzucane na czas definicji, która mogłaby wpłynąć semantyka instancji

template<int I> 
void f(int x[I]); 

int main() { 
    f<0>(nullptr); 
} 

W tym przypadku, moim zdaniem standard normatywnie jest jasne, że parametr jest natychmiast zastępowany przez int*, a tym samym działa instancja. Zobacz http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1322.

+5

"Według wyników spotkań wydaje się, że pożądane jest zachowanie klangów" - czy nie zabiłoby to w ogóle jakiegokolwiek aliasu "EnableIf"? Wygląda na to, że bardzo niepożądane jest, aby szablony aliasów nie generowały błędów soft-in SFINAE. – Xeo

+0

@Xeo tak, byłoby źle. W rzeczywistości, klang trunk akceptuje alias "EnableIf", więc wydaje mi się, że zachowanie, które pytał obserwujący, było tylko błędem klang, i że podsumowanie tego problemu na stronie wg21 jest po prostu mylące (IMHO). –

+0

Tak, byłem zdezorientowany, ponieważ już zauważyłem, że bagażnik kompiluje kod dobrze. – Xeo