2011-08-19 21 views
6

Esto debería ser auto explicativo. Estoy tratando de implementar una ordenación de distribución, y el compilador de MSVC se está bloqueando. Parece que hay que hacer un caso específico con mi SFINAE para detectar una función de miembro, esto no parece suceder si no paso indexert a una función, ni si reemplazo has_get_index. Tampoco sucede si elimino cualquiera de las sobrecargas restantes del indexador. El problema persiste si sortable tiene un miembro getIndex() const.C1001: Se ha producido un error interno en el compilador

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. 

(No hay "lugares indicados más arriba") Un caso de prueba mínima es:

#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

Intente archivar un error en http://connect.microsoft.com/ –

+0

Hm, no estoy seguro de su error, pero la [impresora bonita] (http://louisdx.github.com/cxx-prettyprint/) tiene un rasgo de SFINAE para los tipos de miembros y las funciones de los miembros, se puede echar un vistazo a eso. –

+0

@Kerrek el código de impresora bonito afirma "rasgo de tipo SFINAE para detectar si" T :: const_iterator T :: begin/end() const "existe", pero realmente comprueba si hay algún miembro llamado "begin" y "end". no específicamente una función ... Parece que el tipo que codificó esa lib copia parcialmente algunas respuestas de stackoverflow, sin entender cómo funcionan. –

Respuesta

5

Esto probablemente no es lo que pretende:

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

Con typename le dice el compilador que C::func será un tipo. En realidad, será una función, y poner un nombre de función allí en la declaración de parámetro no tiene ningún sentido.

¿Quizás intentó usar typeof en lugar de typename?

+2

Bueno, eso detiene la falla del compilador. ¡Boo Microsoft! –

Cuestiones relacionadas