一个变量怎么可能既是constexpr又不是constexpr
How can a variable be both constexpr and not constexpr?
我创建了一个constexpr
字符串类型,称之为StaticString
。我是从这个网站上得到这个想法的。
我遇到了一些奇怪的问题,编译器在一行中将变量视为constexpr
,然后在下一行将变量视为不属于constexpr
。
这是代码:
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 is constexpr?)
//constexpr StaticString both3 = "hello " + world;
//ERROR: "world" is not constexpr
int main(void)
{
static_assert(hello[4] == 'o' ,"ERROR");
static_assert(hello == "hello", "ERROR");
static_assert(both2 == "hello world", "ERROR");
}
这是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 the null terminating char
{
static_assert(N>=1,"String cannot have a 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;
}
所以我的问题是:为什么world
在一行被视为constexpr
,而在下一行却没有?
注意:这是我得到的错误:
'StaticString{((const char*)"world"), 5ull, ((const prototypeInd::util::StaticString*)(&<anonymous>))}' is not a constant expression
此外,我正在使用gcc
讨论
您的world
变量是constexpr
,但表达式中的operator+
constexpr StaticString both3 = "hello " + world;
尽管标记为CCD_ 12不是。因为在其返回声明中:
return StaticString(str) + other;
由于创建了指向非静态存储持续时间临时存储器的临时CCD_ 13指针。这是由于在StaticString
对象中存储非静态存储持续时间临时变量的地址,而常量表达式中不允许使用此类指针。
正当性
根据标准§5.20/p5常量表达式[expr.const](Emphasis Mine):
常量表达式要么是glvalue核心常量表达式其值指的是一个实体,该实体是常量表达式(定义如下),或prvalue核心常量其值满足以下约束的表达式:
(5.1)--如果值是类类型的对象,则每个非静态数据引用类型的成员指的是允许的实体常数表达式的结果
(5.2)--如果值为指针类型,则它包含具有静态存储持续时间的对象,超过该持续时间末尾的地址对象(5.7)、函数地址或空指针值,和
(5.3)--如果值是类或数组类型的对象,则每个子对象满足这些值约束
如果实体是常量表达式的允许结果,则它是对象的静态存储持续时间不是临时的对象或是值满足上述条件的临时对象约束,或者它是一个函数。
。
相关文章:
- 头文件可以在主类中运行.这怎么可能?
- 怎么可能只让设备使用 pjsua2 捕获或播放
- std::lock_guard 怎么可能比 std::mutex::lock() 更快?
- 怎么可能写 f( *this, std::forward<Args>(args)... ) 而 f 只用 F f 声明;
- 在QT C++编辑Qtable模型数据时,我需要得到一个小盒子,我需要显示编辑文本,这怎么可能?
- 在给定相同的输入的情况下,某些代码怎么可能花费更多时间来运行,这似乎只是因为它处于循环中?
- 答案怎么可能是433?
- 八进制文字怎么可能是负数?
- 我们可以在整数类型的双指针中分配2D整数数组的地址吗?怎么可能
- 我怎么可能从尚未定义某些成员方法的类创建实例?(C++)
- 使用 stl 迭代器封装向量是否很好?如果是?怎么可能呢?
- 几个比较怎么可能比一些计算慢
- 我的 Cuda 矢量怎么可能在填充后是空的
- 怎么可能有两个同名的变量——一个是全局变量,另一个是局部变量
- 奇怪的交叉播.这怎么可能
- 一个变量怎么可能既是constexpr又不是constexpr
- 如果方法私有,是否可以从 main 调用该方法?如果不是,怎么可能
- ANSI到Unicode或向后转换:怎么可能?
- std::chrono::duration::duration()怎么可能是constexpr
- 这个代码怎么可能是constexpr?(std::chrono)