预处理器在`operator""_name`中定义替换吗

问题描述 投票:0回答:2

考虑 Aykhan Hagverdili 提供的以下示例:

#include <string>

using std::operator""s;

#define s foobar

auto s = "hello world"s;

某些编译器会替换

s
并导致编译失败。 有些编译器不会替换
s

在此处查看结果:https://godbolt.org/z/jx4nhYczd gcc 失败,clang 编译

哪个是对的?

c++ language-lawyer c-preprocessor user-defined-literals
2个回答
10
投票
自 C++11 起,

"hello world"s
是与 用户定义的字符串文字语法生成相匹配的单个预处理标记。

宏在预处理标记级别上进行替代。由于没有

s
预处理标记,因此无法替换您的宏。

因此,您的代码在 C++14 或更高版本中格式良好。选择

std::operator""s
。在 C++11 中没有
std::operator""s

但是,在 C++11 引入用户定义文字之前,

"hello world"s
将是两个预处理标记
"hello"
s
,因此后一个将被替换为您的宏。

这甚至在 [diff.cpp03.lex]/2 中明确提到为与 C++11 向后不兼容的更改。


3
投票

GCC 错了。

"hello world"s
这样的用户定义字符串文字是一个预处理标记,而不是两个预处理标记
"hello world"
s
。预处理器不应替换预处理令牌的一部分。

© www.soinside.com 2019 - 2024. All rights reserved.