Следующий код в C ++ 11 правильно компилируется с g ++ 6.3.0 и приводит к поведению, которое я считаю правильным (а именно, выбрана первая функция).Однако с компилятором Intel C ++ (icc 17.0.4) он не компилируется;компилятор указывает, что существует несколько возможных перегрузок функций.
#include <iostream>
template<typename R, typename ... Args>
static void f(R(func)(const int&, Args...)) {
std::cout << "In first version of f" << std::endl;
}
template<typename R, typename ... Args, typename X = typename std::is_void<R>::type>
static void f(R(func)(Args...), X x = X()) {
std::cout << "In second version of f" << std::endl;
}
double h(const int& x, double y) {
return 0;
}
int main(int argc, char** argv) {
f(h);
return 0;
}
Вот ошибка, о которой сообщает icc:
test.cpp(18): error: more than one instance of overloaded function "f" matches the argument list:
function template "void f(R (*)(const int &, Args...))"
function template "void f(R (*)(Args...), X)"
argument types are: (double (const int &, double))
f(h);
^
Итак, два моих вопроса: какой компилятор корректен по отношению кстандарт?и как бы вы изменили этот код, чтобы он компилировался?(обратите внимание, что f
- это API-интерфейс, ориентированный на пользователя, и я не хотел бы изменять его прототип).
Обратите внимание, что если я удаляю typename X = typename std::is_void<R>::type
и аргумент X x = X()
во второй версии f
, icc компилирует это нормально.