确保字符指针始终指向相同的字符串文字
Ensure that char pointers always point to the same string literal
给定代码
// somewhere in the program
const char* p1 = "Hello World";
// somewhere else in the program
const char* p2 = "Hello World";
有没有办法确保p1 == p2
在整个程序/库中始终得到满足?我的意思是p1
和p2
总是引用相同的字符串文字。
背后的原因
我试图实现的是使用const char*
作为std::map<const char*, something>
的密钥。我有一个宏
#define nameof(id) #id
它模仿了C#中nameof
关键字的行为(我知道这已经有缺陷了(,我想用它来访问类似注册表的结构,例如
void foo()
{
auto x = getMapping(nameof(foo));
}
// different place in code
void registerFoo(something x)
{
setMapping("foo", x);
}
正如Barry在他们的回答中所表明的那样,你想要的行为并不能得到保证。您将不得不支付字符串比较的费用,但您至少可以通过使用std::string_view
来避免任何内存分配或编写比较器。std::string_view
是字符串的轻量级视图,它包含指向字符串数据和字符串大小的指针,并且它有一个内置的operator <
,可以进行字典比较。那会把你的地图改成
std::map<std::string_view, something>
没有这样的要求。[lex.string]/15:
是否所有字符串文字都是不同的(即存储在不重叠的对象中(,以及字符串文字的连续求值是产生相同的对象还是产生不同的对象,都未指定。
你能做的最好的事情是assert()
,或者只是避免重复你自己,把事情放在一个函数中:
char const* my_literal() { return "Hello World"; }
char const* p1 = my_literal();
char const* p2 = my_literal();
相同的文字字符串不能保证是相同的,但是当您使用MACRO创建字符串时,您可以将其更改为返回相同的字符串。
gcc/clang有一个扩展,允许从文字字符串构建UDL:
template<typename Char, Char... Cs>
struct CsHelper
{
static constexpr const Char s[] = {Cs..., 0}; // The unique address
};
// That template uses the extension
template<typename Char, Char... Cs>
constexpr auto operator"" _cs() -> const Char (&)[1 + sizeof...(Cs)] {
return CsHelper<Char, Cs...>::s;
}
然后
#define nameof(id) #id ## _cs
请参阅我在compiletime的String interning中的回答,如果您不能使用扩展,则可以使用MAKE_STRING
宏进行分析(对于可接受的字符串长度,确实更详细,并且是硬编码的限制(。
不要求具有相同文本的两个字符串文字是同一对象。因此,”Hello world”
的两次提及可能指代也可能不指代存储器中的单个字符串。这意味着
const char* p1 = "Hello World";
const char* p2 = "Hello World";
并不一定使p1
等于p2
。要做到这一点,你必须将其中一个设置为与另一个相等:
const char* p2 = p1;
但其中任何一个指针都可以修改,而另一个指针不会跟踪这种变化。为了确保不能进行这样的更改,请将指针设为常量:
const char* const p1 = "Hello World";
const char* const p2 = p1;
或者,如果p1
需要修改,则将p2
作为参考:
const char* p1 = "Hello World";
const char*& p2 = p1;
现在p2
将指向上的任何p1
点
我不知道它是否有帮助,但在Visual Studio
中有一个名为"的C++选项;启用字符串池";。
/GF(消除重复字符串(
使编译器能够在程序图像和执行期间的存储器中。这是一个称为字符串池的优化,可以创建更小的程序。
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 如何使用字符串文字作为宏参数
- 有没有办法从非C/C++文件中读取C++原始字符串文字的内容
- 构造<int>具有 2 个字符串文字的向量
- 初始化或分配空字符串文字到指向 C 中的 char 的指针或指向 C++ 中 const char 的指针的原因是什么
- 方便地对C++中的所有字符串文字进行模糊处理
- 比较 std::string 和 C 样式字符串文字
- 如何从char16_t字符串文字中读取双精度?
- 如果我在块中编写字符串文字,是否会从数据部分复制整个字符串数据?
- C++ 不能在cout中使用向量和字符串文字
- 为什么必须将 const 添加到 constexpr 中才能进行字符串文字声明?
- C++:Unicode 字符串文字的可移植性
- 返回空字符串文字 VS. 返回空点 - 它们是一样的吗?
- 确保字符指针始终指向相同的字符串文字
- 如何按照 Google C++风格指南连接字符串文字?
- 通过 constexpr 中的 'const char *' glvalue 访问字符串文字的值会出错
- 字符串文字到 char 数组的转换如何在C++中实际工作
- 另一个字符串文字,UDL 迷宫
- strlen 是否针对字符串文字进行了优化?
- 用户定义的字符串文字为字符串null终止