Следующий код дает ошибку компиляции как с g cc, так и с clang.
typedef void (*Function)();
template<class T, void (T::*M)()>
void function() {
}
template<class T>
void bind(void (T::*M)(), T * object) {
Function f = &function<T, M>;
}
struct Test {
void receive() { }
};
int main(int, char**) {
Test t;
bind(&Test::receive, &t);
return 0;
}
Clang дает более значимую ошибку:
758453603/source.cpp:9:19: error: address of overloaded function 'function' does not match required type 'void ()'
Function f = &function<T, M>;
^~~~~~~~~~~~~~ 758453603/source.cpp:19:5: note: in instantiation of function template specialization 'bind<Test>' requested here
bind(&Test::receive, &t);
^ 758453603/source.cpp:4:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'M' void function() {
Дело в том, что значение указателя функции который передается в функцию bind () , зависит от параметра шаблона T и, следовательно, может быть полностью разрешен во время компиляции, поэтому теоретически компилятор имеет всю необходимую информацию для успешной компиляции. Однако кажется, что компиляторы предполагают, что код пытается использовать переменную времени выполнения для спецификации типа шаблона и выдает ошибку. Для меня это указывает на дефект либо в реализации компилятора, либо в спецификации C ++, но, возможно, я что-то упускаю.