简体   繁体   中英

Forbids functions with `static_assert`

I want to prevent certain functions from being called. Let's ignore the case of calling the function via a function pointer or something, and just concentrate on the case of direct function call. I can do this with = delete . However, the diagnostic issued is not quite informative. I considered using static_assert , with which you can supply a custom diagnostic message. I placed a static_assert(false, ...) statement within the function body, hoping that it fires when the function is called. However, it turns out that the static_assert fails even if the function is not called. Any suggestions?

Additional Note: The function is forbidden unconditionally. So, std::enable_if does not apply here. The motivation for such a function is that I want to prevent certain use, which would otherwise compile fine with overload resolution. So I can't just remove the function. deprecated is not what I want. I want a compilation error, not a warning.

I agree with others that you shouldn't use static_assert for this at all and mark the function as deprecated instead.

static_assert ions fire at the time they are compiled. For an ordinary function, this is the time it is parsed, not the time it is called. For a template , however, it is the time of instantiation. So you can make your function a template like this.

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!");
}

If typename... is not right for you (because the function is overloaded), try narrowing it down to only match what you want to make an error.

The trick used here is that always_false<Ts...>::value depends on the type parameters Ts... so it cannot be evaluated until the template is instantiated. (Even though we can clearly see that it will always be false .)

If it is a member function then = delete is your best (most portable) bet. Otherwise, both GCC and MSVC have support for marking a function as "deprecated", which will cause the compiler to issue a warning when the function is called.

From C++ mark as deprecated :

#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

Usage:

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

.... and now with C++ 14, we can write it as:

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

With usage:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM