Ответ 1
На основе комментариев по вашему вопросу вы не хотите static_assert
здесь:
template <typename T>
auto Function(T value) -> std::enable_if<someCondition, int>
{
// this is the function I want to call
}
... но здесь нет ничего плохого в static_assert
здесь:
template <typename... T>
struct dependent_false { static constexpr bool value = false; };
template <typename... T>
int Function(T...)
{
static_assert(dependent_false<T...>::value, "you are passing the wrong arguments!");
}
Как вы правильно отметили, простой static_assert(false, "...");
завершится неудачей во время определения шаблона. Чтобы получить то, что только не выполняется во время создания экземпляра, вам нужно зависимое выражение, а вспомогательная структура dependent_false
- это простой способ получить то, что будет зависящим от типа, будет всегда всегда false
, но не может быть принято компилятором по-настоящему всегда быть false
: компилятор не может исключить добавление частичных специализаций для создания dependent_false<...>::value
true
для некоторого типа.
Оглядываясь назад на этот старый вопрос, может быть гораздо более простой ответ: отметьте перегрузку как удаленную.
template <typename T>
auto Function(T value) -> std::enable_if<someCondition, int>
{
// this is the function I want to call
}
template <typename... T>
int Function(T...) = delete;
Это не совсем то же самое, поскольку это позволяет вызывающему лицу проверить правильность формы, например. Function(int, int)
вместо того, чтобы вызывать ошибку, но это более читаемо, и обычно вам нужно, чтобы точное поведение не получало ошибку, если функция фактически не используется, а не просто ссылается.