Reputation: 66932
This should be self explanatory. I'm trying to implement a distribution sort, and the MSVC compiler is crashing. It seems to be a specific case to do with my SFINAE to detect a member function, this doesn't appear to happen if I don't pass indexert to a function, nor if I replace has_get_index. It also doesn't happen if I remove either of the remaining indexer overloads. The problem does remain if sortable has a getIndex() const
member.
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.
(There are no "locations listed above") A minimal test case is:
#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
}
Upvotes: 6
Views: 9039
Reputation: 229663
This probably isn't what you intended:
template <typename C> static yes& test( typename C::func ) ;
With typename
you tell the compiler that C::func
will be a type. In reality it will be a function, and putting a function name there in the parameter declaration doesn't make any sense.
Did you maybe intend to use typeof
instead of typename
?
Upvotes: 5