Ответ 1
Похоже, вы попали в дефект в стандарте, который еще предстоит решить. Итак, ответ на вопрос: "Какой компилятор прав?" в настоящее время не совсем ясны.
Этот вопрос был поднят и обсужден комитетом:
Неясно, правильно ли сформировано следующее:
void foo(){} template<class T> void deduce(const T*) { } int main() { deduce(foo); }
Реализации различаются в их отношении к этому примеру.
см. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584, но предлагаемая резолюция не является частью N4141 или N4659.
Обратите внимание, что вы вообще не можете иметь указатели на типы функций const
; если вы рассмотрите пример, который я назвал плохо сформированным, gcc будет правильным. Он отвергает пример и в OP выбирает неконстантную версию как единственную жизнеспособную перегрузку.
Если бы clang (претендующий на реализацию предлагаемой резолюции) был бы прав в противном случае, я не уверен. Думаю, нам придется пересмотреть эту дискуссию, как только комитет разрешит проблему с некоторыми нормативными формулировками, которые мы можем использовать.
Тем не мение,
Консенсус CWG заключался в том, что cv-квалификация аргумента и параметра должна соответствовать, поэтому исходный пример должен быть отклонен.
(примечание к указанной проблеме), похоже, указывает на то, что gcc прав, и проблема будет решена в пользу его поведения.