Ни один из компиляторов здесь не прав, поскольку программа имеет неопределенное поведение.
Обратите внимание, что MSVC, конечно, выдает ошибки, если вы на самом деле пытаетесь вызвать связанный функтор.Таким образом, вопрос довольно академичен, поскольку в реальной программе, использующей std::bind
для создания чего-то, что никогда не может быть вызвано ни при каком пути кода, это не очень полезно.
C ++ 17 [func.bind.bind] / 2 говорит:
Требуется: ... INVOKE (fd, w_1, w_2, ..., w_N)
должно быть допустимым выражением для некоторых значений w_1
, w_2
,... w_N
, где N
имеет значение sizeof...(bound_args)
....
Но это требование к коду, использующему стандартную библиотеку, а не к реализациям (компиляторам и / или библиотекам), и ничто не говорит о том, что реализации должны диагностировать нарушение.Нарушение Требуется: параграф является неопределенным поведением, если не указано иное.
Так что способность g ++ и clang ++ (при использовании libstdc ++) замечать проблему при вызове std::bind
просто приятнаБонус за качество реализации.
Предположительно libstdc ++ делает это путем сопоставления шаблона с указателем на (член) функцию.Но в более общем случае определить, существует ли какой-либо способ вызова функтора с заданным числом аргументов подстановочных знаков, более сложно или невозможно.Все три компилятора принимают этот код без ошибок и предупреждений:
#include <functional>
struct X {
void operator()() const;
void operator()(int) const;
};
void f() {
auto func = std::bind(X{}, 2, 3, 4);
static_cast<void>(func);
}