#include <stdio.h>
constexpr size_t constLength(const char* str)
{
return (*str == 0) ? 0 : constLength(str + 1) + 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
const char* p = "1234567";
size_t i = constLength(p);
printf(p);
printf("%d", i);
return 0;
}
嗨,所有 我想在compile-time中得到一个字符串的长度。所以我写了上面的代码。但是在反汇编代码中我发现'constLength'函数,下面命名为sub_401000将导致运行时开销,用于计算字符串的长度。是那里有什么不对吗?(Visual Studio 2015 Preview,最大化速度(/ O2)优化发布)
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;
}
答案 0 :(得分:7)
只有在使用编译时常量参数调用时,才能在编译时评估constexpr
函数。尽管p
的值可以通过静态分析确定(它在初始化和评估之间不会改变),但它不是每个标准定义的常量表达式。
试试这个:
constexpr const char* p = "1234567";
此外,通过将初始化变量声明为constexpr
,您可以保证初始化在没有运行时开销的情况下可行:
constexpr size_t i = constLength(p);
答案 1 :(得分:1)
在C ++ 17中,您可以使用std::char_traits::length
constexpr auto l = std::char_traits<char>::length("123");//string("123").length();
cout << l;
答案 2 :(得分:0)
要在编译时强制执行评估,有一些技巧。 首先,您可以在枚举中使用该值。但是,这会用“垃圾”枚举污染您的命名空间。
您还可以使用一个简单的模板在编译时强制进行评估。参见static_eval.h。模板很小:
template<typename T, T V>
struct static_eval
{
static constexpr T value = V;
};
然后,您可以将该模板与上面的代码一起使用,类似于以下内容: // size_t i = constLength(p); size_t i = static_eval :: value;
这将强制执行编译时评估,或者如果表达式未评估为constexpr,则会强制发生编译时错误。