在我看来,拥有"总是返回5的功能"正在破坏或淡化"调用函数"的含义.必须有一个原因,或者需要这种能力,或者它不会出现在C++ 11中.为什么会这样?
// preprocessor.
#define MEANING_OF_LIFE 42
// constants:
const int MeaningOfLife = 42;
// constexpr-function:
constexpr int MeaningOfLife () { return 42; }
Run Code Online (Sandbox Code Playgroud)
在我看来,如果我编写了一个返回字面值的函数,并且我进行了代码审查,有人会告诉我,我应该声明一个常量值而不是写回返5.
我想要一个在其构造函数中包含两个参数的类.第一个可以是int,double或float,所以<typename T>,第二个总是字符串文字"my string",所以我想const char * const.
任何人都可以给我一些可编译的代码,声明一个简单的类模板,并声明该类的对象?
谢谢
可以在运行时创建C-Strings还是std::string必须创建constexpr它们?
使用gcc 4.9.2我可以这样做:
constexpr const char foo[] = "blee";
Run Code Online (Sandbox Code Playgroud)
(遗憾的是,2013年11月的客户技术预览版不允许Visual Studio支持此功能:https://stackoverflow.com/a/29255013/2642059)
但即使使用gcc 4.9.2我也不能这样做:
constexpr const std::string foo = "blee";
Run Code Online (Sandbox Code Playgroud)
我收到错误:
error: the type 'const string {aka const std::basic_string<char>}' of constexpr variable 'foo'
is not literal
constexpr const std::string foo = "blee";
^
note: 'std::basic_string<char>' is not literal because:
class basic_string
^
note: 'std::basic_string<char>' has a non-trivial destructor
Run Code Online (Sandbox Code Playgroud)
但我想更多地澄清为什么 a std::string不是文字.也就是说:为什么必须在运行时构造字符串?
正如所指出的,这个问题可以部分回答:是否可以在constexpr中使用std :: string?但它没有涉及为什么std::string不能成为问题核心的文字.
我可以创建constexprstd :: array:
constexpr std::array<int,5> values {1,2,3,4,5};
Run Code Online (Sandbox Code Playgroud)
它工作正常.但我无法创建constexpr矢量:
constexpr std::vector<int> vec = {1,2,3,4,5};
Run Code Online (Sandbox Code Playgroud)
它给了我一个错误:
the type 'const std::vector<int>' of constexpr variable 'vec' is not literal constexpr std::vector<int> vec = {1,2,3,4,5};
我想消除代码中对 #define 宏的依赖,但我无法使用constexpr.
为了实用,请考虑以下示例:
\n#define PRODUCT_NAME "CloysterHPC"\nconstexpr const char* productName = PRODUCT_NAME;\n\nclass Newt : public View {\nprivate:\n struct TUIText {\n\n#if __cpp_lib_constexpr_string >= 201907L\n static constexpr const char* title =\n fmt::format("{} Installer", productName).data();\n#else\n static constexpr const char* title = PRODUCT_NAME " Installer";\n#endif\n\n };\n};\nRun Code Online (Sandbox Code Playgroud)\n我经历了惨痛的教训才知道fmt::format()函数不是constexpr函数,它只是一个运行时函数。我本以为我可以在代码中更具表现力,但我不能。所以我尝试使用std::string,但在将代码更改为类似以下内容后,我再次得到了相同的确切结果:
#define PRODUCT_NAME "CloysterHPC"\nconstexpr const char* productName = PRODUCT_NAME;\n\nclass Newt : public View {\nprivate:\n struct TUIText {\n\n#if __cpp_lib_constexpr_string >= 201907L\n static constexpr const char* title = …Run Code Online (Sandbox Code Playgroud) 为什么不编译:作为返回类型
会出现问题string吗?
constexpr std::string fnc()
{
return std::string("Yaba");
}
Run Code Online (Sandbox Code Playgroud) 注意:我使用的是 gcc,但在 godbolt.org 上进行了测试,它也适用于 msvc,但不适用于 clang
\n我意外地发现以下简单函数在模板类中进行编译,但不能作为自由函数进行编译。有人可以解释为什么吗?
\n编译正常:
\n template <typename T = void>\n class A\n {\n public:\n static constexpr std::string f()\n {\n return std::string();\n }\n }\nRun Code Online (Sandbox Code Playgroud)\n不编译:
\n constexpr std::string f()\n {\n return std::string();\n }\nRun Code Online (Sandbox Code Playgroud)\n抛出错误:
\nerror: invalid return type \xe2\x80\x98std::string\xe2\x80\x99 {aka \xe2\x80\x98std::__cxx11::basic_string<char>\xe2\x80\x99} of \xe2\x80\x98constexpr\xe2\x80\x99 function ...\n...\n/usr/include/c++/9/bits/basic_string.h:77:11: note: \xe2\x80\x98std::__cxx11::basic_string<char>\xe2\x80\x99 is not literal because:\n 77 | class basic_string\n | ^~~~~~~~~~~~\n/usr/include/c++/9/bits/basic_string.h:77:11: note: \xe2\x80\x98std::__cxx11::basic_string<char>\xe2\x80\x99 has a non-trivial destructor\nRun Code Online (Sandbox Code Playgroud)\n