2016-06-21 11 views
7

Aktualizacja Visual Studio 2015 3 poprawiono obsługę C++ 11, ale mam dziwny problem i szukam obejścia.Aktualizacja MSVC2015 3 obejście szablonu zastępczego

Podczas kompilowania kodu variadic-template z MSVC dla argumentów typu szablonu ("w pełni zdefiniowane typy") wszystko działa dobrze, ale jeśli chcę użyć argumentów szablonu szablonu ("typy częściowo zdefiniowane"), wynik staje się niepoprawny.

#include <iostream> 
using namespace std; 

template <template<typename> class... TS> 
struct PARTIAL { 
    static void test(std::ostream& out) 
    { 
     out << "PARTIAL-PROBLEM" << endl; 
    } 
}; 
template <template<typename> class T> 
struct PARTIAL<T>{ 
    static void test(std::ostream& out) 
    {out << "PARTIAL-OK-END" << endl;} 
}; 
template <template<typename> class T, template<typename> class... TS> 
struct PARTIAL<T, TS...>{ 
    static void test(std::ostream& out) 
    { 
     out << "PARTIAL-OK" << endl; 
     PARTIAL<TS...>::test(out); 
    } 
}; 

template <class... TS> 
struct FULL { 
    static void test(std::ostream& out) 
    { 
     out << "FULL-PROBLEM" << endl; 
    } 
}; 
template <class T> 
struct FULL<T>{ 
    static void test(std::ostream& out) 
    {out << "FULL-OK-END" << endl;} 
}; 
template <class T, class... TS> 
struct FULL<T, TS...>{ 
    static void test(std::ostream& out) 
    { 
     out << "FULL-OK" << endl; 
     FULL<TS...>::test(out); 
    } 
}; 
template <typename T> 
struct B{}; 
int main() 
{ 
    FULL<int, int, int>::test(cout); 
    PARTIAL<B, B, B>::test(cout); 
    return 0; 
} 

Wyjście GCC5.3 (Mingw)

FULL-OK 
FULL-OK 
FULL-OK-END 
PARTIAL-OK 
PARTIAL-OK 
PARTIAL-OK-END 

Wyjście MSVC:

FULL-OK 
FULL-OK 
FULL-OK-END 
PARTIAL-OK 
PARTIAL-OK 
PARTIAL-OK 
PARTIAL-PROBLEM 

MSVC wytwarza kod inny sposób dla pełnych określonych rodzajów i podszablonów. Jakie powinno być najlepsze obejście tego?

here is demo that works good on GCC

+2

Wygląda bug do mnie. – Arunmu

+0

Zastąp '-OK' w kończącej się sprawie' -OK-TERMINATE', aby uczynić problem bardziej oczywistym. Ogranicz także swój kod do problemu: kod, który działa, jest w pewnym sensie nieinteresujący. Zauważ, że nie są to "typy częściowe", ale raczej "parametry szablonu szablonu". – Yakk

+0

Zaktualizowany, nie chcę usuwać części roboczej. Może ktoś znajdzie rozwiązanie dla obu przypadków użycia. – Evgeniy

Odpowiedz

4

Dodanie kolejnego parametru na rekurencyjnym przypadku będzie upewnić się, że nie został wybrany dla przypadku obciążeniowym:

template <template<typename> class T, template<typename> class T2, template<typename> class... TS> 
//         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
struct PARTIAL<T, T2, TS...>{ 
//    ^^^^ 
    static void test(std::ostream& out) 
    { 
     out << "PARTIAL-OK" << endl; 
     PARTIAL<T2, TS...>::test(out); 
       ^^^^ 
    } 
}; 
+0

Tak, działa to zgodnie z oczekiwaniami. Dzięki! – Evgeniy

Powiązane problemy