2016-06-21 8 views
7

Visual Studio 2015 Update 3 verbesserte Unterstützung von C++ 11 viel, aber ich habe seltsames Problem, und ich suche nach einer Problemumgehung.MSVC2015 Update 3 variadic Vorlage Problemumgehung

Beim Kompilieren variadische-Template-Code mit MSVC für Argumente Vorlagentyp („fully-Typen definiert“) alles funktioniert gut, aber wenn ich ein Template Argumente verwenden möchten („teilweise Typen definiert“), wird das Ergebnis nicht korrekt.

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

Der Ausgang des GCC5.3 (mingw):

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

Der Ausgang des MSVC:

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

MSVC für volle definierten Typen und partials Code unterschiedliche Weise erzeugt. Was sollte die beste Problemumgehung sein?

here is demo that works good on GCC

+2

Sieht aus wie ein mir Fehler. – Arunmu

+0

Ersetzen Sie die "-OK" im abschließenden Fall mit "-OK-TERMINATE", um das Problem deutlicher zu machen. Verringern Sie auch Ihren Code auf das Problem: Der Code, der funktioniert, ist in gewisser Weise uninteressant. Beachten Sie, dass dies keine "Partialtypen" sind, sondern "Vorlagenvorlagenparameter". – Yakk

+0

Aktualisiert, ich möchte das Arbeitsteil nicht entfernen. Vielleicht findet jemand eine Lösung für beide Anwendungsfälle – Evgeniy

Antwort

4

einen anderen Parameter der rekursiven Fall Hinzufügen wird sichergestellt, dass es nicht für den Abschluss Fall ausgewählt wird:

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

Ja, das funktioniert wie erwartet. Vielen Dank! – Evgeniy