C++11: Compile-time value checking of constructor arguments possible?
Marc Glisse
marc.glisse@inria.fr
Thu Mar 15 21:34:00 GMT 2012
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
More information about the Gcc-help
mailing list