I think it would be nice to have a test for const(expr)-ness of a variable, to be used like:
struct T {
...
static_assert(!IS_CONSTANT_VAR(value) || value > 0, "trouble is afoot");
};
The implementation below uses a similar strategy to kennytm's solution to fail out on non-constant references. It works in Clang and GCC.
#include <type_traits> // enable_if
template<typename T, T& var, typename = void> struct is_constant_var_impl {
static constexpr bool value = false;
};
template<typename T, T& var>
struct is_constant_var_impl <T, var, typename std::enable_if<(double)var == (double)var>::type> {
// (double) cast above to thwart GCC's agressive constant folding;
// perhaps could be removed with a bit more finesse
static constexpr bool value = true;
};
#define IS_CONSTANT_VAR(...) (is_constant_var_impl<decltype(__VA_ARGS__), (__VA_ARGS__)>::value)
Pros
- Template can be reused across different classes or static member names
- Self-explanatory code in the
static_assert
Cons
- Does not work in MSVC
- (Maybe?) Uses C++14
- Gross