问题
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.
回答1:
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
.)
回答2:
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");
来源:https://stackoverflow.com/questions/34745581/forbids-functions-with-static-assert