2011-08-19 19 views
6

Questo dovrebbe essere auto esplicativo. Sto cercando di implementare un ordinamento di distribuzione e il compilatore MSVC si arresta in modo anomalo. Sembra essere un caso specifico da fare con il mio SFINAE per rilevare una funzione membro, questo non sembra accadere se non passo l'indexert a una funzione, né se sostituisco has_get_index. Inoltre, non succede se rimuovo uno dei sovraccarichi dell'encoder rimanente. Il problema rimane se sortable ha un membro getIndex() const.C1001: si è verificato un errore interno nel compilatore

1>test.cpp(34): fatal error C1001: An internal error has occurred in the compiler. 
1> (compiler file 'msc1.cpp', line 1420) 
1> To work around this problem, try simplifying or changing the program near the locations listed above. 

(Non ci sono "posizioni elencate sopra") Un caso di test minima è:

#include <vector> 
#include <iterator> 
#include <type_traits> 

#ifndef HAS_MEM_FUNC //SFINAE (or maybe it is?) 
#define HAS_MEM_FUNC(name, func)          \ 
    template<typename T>            \ 
    struct name {              \ 
     typedef char yes[1];           \ 
     typedef char no [2];           \ 
     template <typename C> static yes& test(typename C::func) ; \ 
     template <typename C> static no& test(...);     \ 
     static bool const value = sizeof(test<T>(0)) == sizeof(yes); \ 
    } 
#endif 
HAS_MEM_FUNC(has_get_index,getIndex); 

//default indexer undefined 
template <class T> 
double indexer(...); 
//indexer for objects that have a "T::getIndex() const" member 
template <class T> 
double indexer(const typename std::enable_if<has_get_index<T>::value,T>::type& b) { 
    return b.getIndex(); 
}; 

template<class indexert> 
void function(indexert indexeri) 
{} 

struct sortable {}; 

int main() { 
    function(indexer<sortable>); //line 34 
} 
+1

Prova a presentare un errore all'indirizzo http://connect.microsoft.com/ –

+0

Hm, non sono sicuro del tuo errore, ma la [stampante carina] (http://louisdx.github.com/cxx-prettyprint/) ha un tratto di SFINAE per entrambi i tipi di membri e le funzioni dei membri, puoi dare un'occhiata a questo. –

+0

@Kerrek il grazioso codice della stampante dichiara "Caratteristica del tipo SFINAE per rilevare se" T :: const_iterator T :: begin/end() const "esiste", ma in realtà controlla i membri chiamati "begin" e "end". non specificamente una funzione ... Sembra che il ragazzo che ha codificato quella lib copiasse in parte alcune risposte StackOverflow insieme, senza capire come funzionano. –

risposta

5

Questo probabilmente non è quella desiderata:

template <typename C> static yes& test(typename C::func) ; 

Con typename si raccontano il compilatore che C::func sarà un tipo. In realtà sarà una funzione, e inserire un nome di funzione nella dichiarazione dei parametri non ha alcun senso.

Forse intendevi utilizzare typeof anziché typename?

+2

Bene, questo impedisce al compilatore di bloccarsi. Boo Microsoft! –

Problemi correlati