2016-06-21 31 views
7

Aggiornamento di Visual Studio 2015 3 Migliorato il supporto di C++ 11 molto, ma ho un problema strano e sto cercando una soluzione alternativa.MSVC2015 aggiornamento 3 modello Variadic soluzione alternativa

Quando si compila il codice del modello variadic con MSVC per gli argomenti del tipo di modello ("tipi completamente definiti") tutto funziona correttamente, ma se si desidera utilizzare gli argomenti del modello di modello ("tipi parzialmente definiti"), il risultato diventa errato.

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

L'uscita GCC5.3 (MINGW):

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

L'uscita MSVC:

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

MSVC produce codice modo diverso per tipi e parziali definiti completi. Quale dovrebbe essere la soluzione migliore di questo?

here is demo that works good on GCC

+2

Sembra un bug per me. – Arunmu

+0

Sostituisci '-OK' nel caso di chiusura con' -OK-TERMINATE' per rendere il problema più ovvio. Inoltre, riduci il codice al problema: il codice che funziona è, in un certo senso, poco interessante. Si noti che quelli non sono "tipi parziali" ma piuttosto "parametri modello di modello". – Yakk

+0

Aggiornato, non voglio rimuovere la parte di lavoro. Qualcuno potrebbe trovare una soluzione per entrambi i casi d'uso – Evgeniy

risposta

4

aggiunta di un altro parametro al caso ricorsivo farà in modo che esso non è selezionato per il caso di terminazione:

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

Sì, funziona come previsto. Grazie! – Evgeniy