注意:这不是关于在转换用例块中使用字符串选择执行路径的。
C ++中的一种常见模式是使用切换用例块将整数常量转换为字符串。看起来像:
char const * to_string(codes code)
{
switch (code)
{
case codes::foo: return "foo";
case codes::bar: return "bar";
}
}
但是,我们使用的是C ++,因此使用std :: string更合适:
std::string to_string(codes code)
{
switch (code)
{
case codes::foo: return "foo";
case codes::bar: return "bar";
}
}
这将复制字符串文字。也许会有更好的方法:
std::string const & to_string(codes code)
{
switch (code)
{
case codes::foo: { static std::string str = "foo"; return str; }
case codes::bar: { static std::string str = "bar"; return str; }
}
}
但这有点丑陋,涉及更多样板。
使用C ++ 14解决此问题的最干净,最有效的解决方案是什么?
答案 0 :(得分:8)
这将复制字符串文字。
是,不是。它将确实复制字符串文字,但是不必分配内存。检查您的实施SSO限制。
您可以使用std::string_view
:
constexpr std::string_view to_string(codes code) {
switch (code) {
case codes::foo: return "foo";
case codes::bar: return "bar";
}
}
您可以找到许多向后移植的版本,例如this one
但是,有时char const*
是正确的抽象。例如,如果要将该字符串转发到需要以null结尾的字符串的API中,则最好返回一个c样式的字符串。
答案 1 :(得分:2)
但这有点丑陋,涉及更多样板。
使用C ++ 14解决此问题的最干净,最有效的解决方案是什么?
要回答上述问题,正如@SamerTufail指出的那样(我也是在工作中亲自做的),我将像这样使用table.stylized {
font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
font-size: 12px;
text-align: left;
border-collapse: collapse;
margin: 4px;
width: 600px;
}
table.stylized thead th {
text-transform: capitalize;
font-size: 13px;
color: #039;
background: #b9c9fe;
padding: 6px;
cursor: pointer;
}
table.stylized tbody tr:nth-child(odd) {
background: #f2f5ff;
}
table.stylized tbody tr:nth-child(even) {
background: #e8edff;
}
table.stylized tbody td {
border-top: 1px solid #fff;
color: #669;
padding: 6px;
height: 1.5em; /* Min row height */
}
table.stylized tbody tr:hover td {
background: #d0dafd;
}
table.stylized tfoot tr {
color: #039;
background: #b9c9fe;
text-align: right;
}
s和<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
。
enum
然后在main()中,您可以得到这样的值,
std::map
我将创建一个用于返回 typedef enum {
foo = 1,
bar = 2,
} Key;
std::map<Key, std::string> hash_map = { {Key::foo ,"foo"}, { Key::bar,"bar"} };
的函数,您将在其中检查std::cout << hash_map.find(Key::foo)->second;
的迭代器,否则该插入器将无效并且使用它将是UB。
编辑:正如其他人在评论中指出的那样,并且根据此question,如果不需要,您可以将second
替换为end()
使元素保持秩序。
根据我的经验,我总是创建std::map
这样的地图。因此,一次创建它们,并多次使用它们摊销创建成本。
答案 2 :(得分:0)
假设您最终想要一个带有标签的std::string
,那么问题是是否要创建它们:
1:在to_string()
中
2:在呼叫者中
使用Compiler Explorer很容易发现。
证明(使用最新的编译器)两者之间没有太大区别。返回const char *
在std::string
#include <string>
char const * to_string(int code)
{
switch (code)
{
case 0: return "foo";
case 1: return "bar";
}
}
std::string foo(int x)
{
std::string s{to_string(x)};
return s;
}
#include <string>
std::string to_string2(int code)
{
switch (code)
{
case 0: return "foo";
case 1: return "bar";
}
}
std::string foo2(int x)
{
std::string s{to_string2(x)};
return s;
}
注意:
foo()
才能阻止编译器进行更大的优化。...to_string()
永远不会返回大于4个字节长的字符串,然后消除了将动态分配堆内存的代码。 结论似乎是,编写自然而整洁的代码几乎不会降低性能。