c++ - How can a variable be both constexpr and not constexpr? -
i have made constexpr
string type, call staticstring
. got idea this website.
i having weird issues compiler treating variable constexpr
on 1 line, , not constexpr
on next line.
here code:
constexpr staticstring hello = "hello"; constexpr staticstring hello2 = hello + " "; constexpr staticstring world = "world"; constexpr staticstring both = hello + " world"; constexpr staticstring both2 = hello2 + world; //this works fine (world constexpr?) //constexpr staticstring both3 = "hello " + world; //error: "world" not constexpr int main(void) { static_assert(hello[4] == 'o' ,"error"); static_assert(hello == "hello", "error"); static_assert(both2 == "hello world", "error"); }
and here definition of staticstring
:
class staticstring{ const char* const str; const size_t len; const staticstring* head; public: template<size_t n> constexpr staticstring(const char(&astr)[n]) : str(astr), len(n-1), head(nullptr) //chop off null terminating char { static_assert(n>=1,"string cannot have negative length"); } template<size_t n> constexpr staticstring(const char(&astr)[n] ,const staticstring* ss) : head(ss), str(astr),len(n-1) { } constexpr staticstring(const char* const astr ,const size_t len,const staticstring* ss = nullptr) : str(astr), len(len), head(ss) { } constexpr char getfromhead(size_t index) const{ return index < head->getsize() ? (*head)[index] : str[index - head->getsize()]; } constexpr char operator[](size_t index) const{ return head ? getfromhead(index) : str[index]; } constexpr size_t getsize() const{ return head ? len + head->getsize() : len; } constexpr bool equals(const char* const other,size_t len,size_t index = 0) const{ return (other[0] == (*this)[index]) ? (len > 1 ? equals(&other[1],len-1,index+1) : true) : false; } template<size_t n> constexpr bool operator==(const char(&other)[n]) const{ return equals(other,n-1); } template<size_t n> constexpr staticstring operator+(const char(&other)[n]) const{ return staticstring(other,this); } constexpr staticstring operator+(staticstring other) const{ return staticstring(other.str,other.len,this); } }; template<size_t n> constexpr staticstring operator+(const char(&str)[n],const staticstring& other){ return staticstring(str) + other; }
so question this: why world
treated constexpr
on 1 line not next?
note: error get:
'staticstring{((const char*)"world"), 5ull, ((const prototypeind::util::staticstring*)(&<anonymous>))}' not constant expression
also using gcc
discussion
your world
variable constexpr
operator+
in expression:
constexpr staticstring both3 = "hello " + world;
although marked constexpr
not. because in return statement:
return staticstring(str) + other;
due creation of temporary staticstring(str)
pointers non-static-storage duration temporaries being created. attributed fact in staticstring
objects you're storing addresses of non-static-storage duration temporaries , these kind of pointers not allowed in constant expressions.
justification
according standard §5.20/p5 constant expressions [expr.const] (emphasis mine):
a constant expression either glvalue core constant expression value refers entity permitted result of constant expression (as defined below), or prvalue core constant expression value satisfies following constraints:
(5.1) — if value object of class type, each non-static data member of reference type refers entity permitted result of constant expression,
(5.2) — if value of pointer type, contains address of object static storage duration, address past end of such object (5.7), address of function, or null pointer value, and
(5.3) — if value object of class or array type, each subobject satisfies these constraints value.
an entity permitted result of constant expression if object static storage duration either not temporary object or temporary object value satisfies above constraints, or function.
.
Comments
Post a Comment