Запрещает функции с помощью static_assert

Я хочу предотвратить вызов определенных функций. Давайте проигнорируем случай вызова функции через указатель функции или что-то еще, и просто сосредоточимся на случае прямого вызова функции. Я могу сделать это с = delete, Однако выданная диагностика не совсем информативна. Я подумал об использовании static_assert, с помощью которого вы можете предоставить пользовательское диагностическое сообщение. Я поместил static_assert(false, ...) оператор внутри тела функции, надеясь, что он срабатывает при вызове функции. Тем не менее, оказывается, что static_assert не удается, даже если функция не вызывается. Какие-либо предложения?

Дополнительное примечание: Функция запрещена безоговорочно. Так, std::enable_if здесь не распространяется Мотивация для такой функции состоит в том, что я хочу предотвратить определенное использование, которое иначе скомпилировалось бы с разрешением перегрузки. Так что я не могу просто удалить функцию. deprecated это не то, что я хочу. Я хочу ошибку компиляции, а не предупреждение.

2

Решение

Я согласен с другими, что вы не должны использовать static_assert для этого вообще и пометьте функцию как устаревшую вместо этого.

static_assertионы загораются в момент их компиляции. Для обычной функции это время анализа, а не время его вызова. Для templateОднако это время создания экземпляров. Таким образом, вы можете сделать свою функцию template как это.

template <typename...>
struct always_false { static constexpr bool value = false; };

template <typename... Ts>
void
never_call_me(Ts&&...)
{
static_assert(always_false<Ts...>::value,
"You should have never called this function!");
}

Если typename... не подходит вам (потому что функция перегружена), попробуйте сузить ее, чтобы соответствовать только тому, что вы хотите сделать ошибку.

Уловка, используемая здесь в том, что always_false<Ts...>::value зависит от параметров типа Ts... поэтому он не может быть оценен до template создается экземпляр. (Хотя мы можем ясно видеть, что это всегда будет false.)

5

Другие решения

Если это функция-член, то = delete ваша лучшая (самая портативная) ставка. В противном случае, и GCC, и MSVC поддерживают маркировку функции как «устаревшей», что заставит компилятор выдавать предупреждение при вызове функции.

От C ++ помечен как устаревший:

#ifdef __GNUC__
#define DEPRECATED(func) func __attribute__ ((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED(func) __declspec(deprecated) func
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED(func) func
#endif

Использование:

DEPRECATED(void badidea(int a, const char* b));

…. и теперь с C ++ 14 мы можем написать это как:

#define DEPRECATED(func, reason) [[deprecated(reason)]] func

С использованием:

DEPRECATED( void badidea(int a, const char* b), "This function was a bad idea");
2

По вопросам рекламы [email protected]