Я хочу предотвратить вызов определенных функций. Давайте проигнорируем случай вызова функции через указатель функции или что-то еще, и просто сосредоточимся на случае прямого вызова функции. Я могу сделать это с = delete
, Однако выданная диагностика не совсем информативна. Я подумал об использовании static_assert
, с помощью которого вы можете предоставить пользовательское диагностическое сообщение. Я поместил static_assert(false, ...)
оператор внутри тела функции, надеясь, что он срабатывает при вызове функции. Тем не менее, оказывается, что static_assert
не удается, даже если функция не вызывается. Какие-либо предложения?
Дополнительное примечание: Функция запрещена безоговорочно. Так, std::enable_if
здесь не распространяется Мотивация для такой функции состоит в том, что я хочу предотвратить определенное использование, которое иначе скомпилировалось бы с разрешением перегрузки. Так что я не могу просто удалить функцию. deprecated
это не то, что я хочу. Я хочу ошибку компиляции, а не предупреждение.
Я согласен с другими, что вы не должны использовать 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
.)
Если это функция-член, то = 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");