2014-06-26 6 views
12

Występuje problem z rozpakowywaniem szablonów variadic do aliasu szablonu.Rozpakowywanie zestawów parametrów w aliasach szablonów

Poniższy kod działa z Clang 3.4 i GCC 4.8, ale nie z GCC 4.9:

template <typename T, typename...> 
using front_type = T; 

template <typename... Ts> 
struct foo 
{ 
    using front = front_type<Ts...>; 
}; 

GCC 4.9 narzeka:

test.cc:7:37: error: pack expansion argument for non-pack parameter 'T' of alias template 'template<class T, class ...> using front_type = T' 
     using front = front_type<Ts...>; 
            ^
test.cc:1:15: note: declared here 
    template <typename T, typename...> 
      ^

Istnieje błąd złożony GCC (#59498), ale jest to ma się nie udać? Oto kontekst z C++ core language issue #1430, "pack expansion into fixed alias template parameter list":

Originally, a pack expansion could not expand into a fixed-length template parameter list, but this was changed in N2555. This works fine for most templates, but causes issues with alias templates.

In most cases, an alias template is transparent; when it's used in a template we can just substitute in the dependent template arguments. But this doesn't work if the template-id uses a pack expansion for non-variadic parameters. For example:

template<class T, class U, class V> 
    struct S {}; 

    template<class T, class V> 
    using A = S<T, int, V>; 

    template<class... Ts> 
    void foo(A<Ts...>); 

There is no way to express A<Ts...> in terms of S , so we need to hold onto the A until we have the T s to substitute in, and therefore it needs to be handled in mangling.

Currently, EDG and Clang reject this testcase, complaining about too few template arguments for A. G++ did as well, but I thought that was a bug. However, on the ABI list John Spicer argued that it should be rejected.

+0

Czy możesz przenieść 'front_type' poza' foo' - wydaje się, że nie są powiązane? – PiotrNycz

+0

Tak, dobry punkt @ Piotrotrycz. (To jednak nie naprawia). – mavam

+0

Sprawdziłem ten zmodyfikowany kod za pomocą gcc4.8 - wygląda na to, że działa. – PiotrNycz

Odpowiedz

9

Doniesiono w gcc4.9 Bugzilla:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59498

Minimal kod do odtworzenia

template <typename T, typename ...> 
using alias = T; 

template <typename ...T> 
using variadic_alias = alias<T...>; 

using Fail = variadic_alias<int>; 

int main() { } 

Z wyjaśnień od gcc ludzi - to jest nie tak oczywiste, że to prawdziwy błąd. To jest nadal dyskusja w gcc bugzilla oraz w DR 1430 (http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430) - podsumowanie w teraz w pytaniu powyżej.

+0

Zgłoszono to jako błąd, ale patrząc na komentarze, które wydają się być przez projekt. –

+0

Tak, wygląda na to, że to się nie uda? Edytowałem pytanie w kontekście z [# 1430] (http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430) – mavam

+0

@ T.C. Dobra uwaga, tęskniłem za tym. – PiotrNycz

Powiązane problemy