Initialize an instance with an integer constant 0, but no other constant variable or integer variable

I want to define a class whose instances can be built, implicitly built, or assigned from an integer constant zero, but not from any other numeric constant, and not from a variable with an integer type (even if its value is zero at run time). It should also be available for copying from other instances of the same class. Using the features of C ++ 11 is in order if they are supported (in the appropriate mode) by both g ++ 4.6 and MSVC 2010.

Specifically, this

class X { /* ... */ }; void fn(X); 

they should all compile:

 X a(0); X b = 0; X c; c = 0; X d = a; X e; e = a; fn(0); 

but this should not:

 X f(1); X g = 1; X h; h = 1; fn(1); int ii = 23; X a(ii); X j = ii; X k; k = ii; fn(ii); 

I tried this, but this did not work:

 class X { public: X() {} constexpr X(int v) { static_assert(v == 0, "must be initialized from zero"); } }; 

& Longrightarrow;

 test.cc: In constructor 'constexpr X::X(int)': test.cc:3:29: error: non-constant condition for static assertion test.cc:3:29: error: 'v' is not a constant expression 
+6
source share
3 answers

If C ++ 0x is required, you can use std::nullptr_t :

 class X { public: X () { } X (std::nullptr_t) { } void operator= (std::nullptr_t) { } }; 

Well, with the drawback that X can also be initialized with nullptr .

+2
source

You need to replace (v == 0) with a constant expression ...

Sort of

 constexpr bool is_zero_construct(size_t number) { return number == 0; } constexpr X(int v) { static_assert(is_zero_construct(v), "must be initialized from zero"); } 
+1
source

You can use the fact that only 0 can be implicitly converted to a pointer:

 struct X { X(); X(void*); }; 

This meets your requirements, but of course it also allows you to initialize a pointer.

0
source

Source: https://habr.com/ru/post/910631/


All Articles