On Thu, 15 Mar 2012, Zack Weinberg wrote:
It's a long story, but I happen to be trying my hand at writing a "safe bit flags" class for C++11 and it would be extremely helpful to be able to do compile-time value checks on constructor arguments. It seems like this should be possible via 'constexpr' constructors that use static_assert inside the constructor body, but it doesn't work with either g++ 4.6 or 4.7. Here's an example: $ cat test.cc // intent is for K instances to be initializable only with an integer // less than or equal to std::numeric_limits<int>::digits #include <limits> struct K { K() = delete; K(const K&) = default; constexpr K(int s) : value(s == 0 ? 0 : 1 << (s-1)) { static_assert(s <= std::numeric_limits<unsigned int>::digits, "overflow"); } const unsigned int value; }; const K good(1); // should compile const K bad(999); // should not compile
You'ld want constexpr on those too (if there was any chance).
$ g++-4.6 -std=c++0x -fsyntax-only test.cc test.cc: In constructor ‘constexpr K::K(int)’: test.cc:10:5: error: non-constant condition for static assertion test.cc:10:5: error: ‘s’ is not a constant expression Same errors with g++ 4.7. If I stick 'constexpr' on the constructor argument as well, I get either a parse error (if 'constexpr' is before 'int') or 'error: a parameter cannot be declared "constexpr"' (if 'constexpr' is after 'int'). (Has C++11 broken the syntax invariant that specifiers and qualifiers can go either before or after the base type? Feh.)
constexpr has nothing to do with const or volatile, it is closer to static if you want a comparison...
Any advice? Solutions that work with 4.6 *strongly* preferred.
Use a factory: make_K<1>() or make_K<999>() ? -- Marc Glisse