C++ c++;11通过constexpr在编译时获取字符串长度

C++ c++;11通过constexpr在编译时获取字符串长度,c++,c++11,constexpr,C++,C++11,Constexpr,constexpr函数只有在使用编译时常量参数调用时才能在编译时求值。尽管可以通过静态分析确定p的值(在初始化和求值之间不会改变),但根据标准定义,它不是一个常量表达式 试试这个: int __cdecl sub_401010() { int v0; // esi@1 v0 = sub_401000("234567") + 1; sub_401040(&unk_402130); sub_401040("%d"); return 0; } in

constexpr
函数只有在使用编译时常量参数调用时才能在编译时求值。尽管可以通过静态分析确定
p
的值(在初始化和求值之间不会改变),但根据标准定义,它不是一个常量表达式

试试这个:

int __cdecl sub_401010()
{
    int v0; // esi@1

    v0 = sub_401000("234567") + 1;
    sub_401040(&unk_402130);
    sub_401040("%d");
     return 0;
}

int __thiscall sub_401000(void *this)
{
  int result; // eax@2

  if ( *(_BYTE *)this )
    result = sub_401000((char *)this + 1) + 1;
  else
    result = 0;
  return result;
}
此外,您还可以通过将初始化变量声明为
constexpr
,来保证在没有运行时开销的情况下进行初始化:

constexpr const char* p = "1234567";

要在编译时强制求值,有两个技巧。 首先,可以在枚举中使用该值。但是,这会用“垃圾”枚举污染名称空间

您还可以使用一个简单的模板在编译时强制求值。看见模板非常小:

constexpr size_t i = constLength(p);
模板
结构静态评估
{
静态constexpr T值=V;
};
然后将该模板与上述代码一起使用,如下所示: //尺寸i=常数长度(p); 大小=静态评估::值

这将强制编译时计算,或者如果表达式的计算结果不是常量表达式,则强制编译时错误。

在C++17中,可以使用

constexpr auto l=std::char_traits::length(“123”)//字符串(“123”).length();

您使用了哪些优化设置,以及使用了哪些编译器和版本?另外,如果使用
constexpr const char*p=“1234567”而不是?(出现问题的原因可能是
p
本身不是
constexpr
,因此编译器将
constelength(p)
的计算推迟到运行时。)我已经尝试过。但这也会导致运行时开销。@ShafikYaghmour如果函数的参数是常量表达式,则可以在编译时计算
constexpr
函数。保证在编译时对其进行求值的唯一方法是在需要常量表达式的上下文中执行求值。@Casey hmmm,我想人们实际上会遵循get上下文的链接这一假设太多了,至少这是我的假设,但我可以看出,没有上下文它是多么误导,将删除。出于好奇:更改为constexpr size\u t constLength(const char*const str)会改变什么吗?1.我尝试了constexpr const char*p=“1234567”。但我得到了与第一次相同的反汇编代码。2.我尝试了constexpr size\u t I=constLength(“1234567”)然后出现编译错误:严重性描述项目文件行错误C2127:“i”:使用非常量非法初始化“constexpr”实体expression@LeonhartSquall“那听起来像是一个编译器错误。”Leonhartswall说
constexpr size_t i = constLength(p);
template<typename T, T V>
struct static_eval
{
    static constexpr T value = V;
};
constexpr auto l = std::char_traits<char>::length("123");//string("123").length();
cout << l;