使用用户定义的文字在C++ 11中有条件地包含?

And*_*zos 6 c++ c++11

在C++ 11中,当一个表单的预处理指令...

#if expr
Run Code Online (Sandbox Code Playgroud)

遇到......,如下所述expr进行评估.constant-expression16.1 [cpp.cond]

这是在宏替换之后完成的expr,其标识符(和关键字)被替换为0,它preprocessing-tokens被转换为tokens,defined运算符被评估,等等.

当令牌之一,我的问题是会发生什么expruser-defined-literal

用户定义的文字就像函数调用,但函数调用不能发生在expr(我认为)中,作为标识符替换的副作用.但技术上user-defined-literals可以存活下来.

我怀疑这是一个错误,但我不明白如何从标准中得出结论?

也许[cpp]忽略了在第16条中添加用户定义文字的(迂腐)影响?

或者我错过了什么?

更新:

通过一个例子澄清:

这预处理到什么:

#if 123_foo + 5.5 > 100
bar
#else
baz
#endif
Run Code Online (Sandbox Code Playgroud)

吧或巴兹还是错误的?

GCC 4.7报告:

test.cpp:1:5: error: user-defined literal in preprocessor expression
Run Code Online (Sandbox Code Playgroud)

所以它认为这是一个错误.这可以参考标准来证明吗?或者这只是"隐含的"?

Joe*_*rgB 3

#if expr ...在 C++11 中,当遇到 ...形式的预处理指令时,将按中所述expr计算为 a 。constant-expression16.1 [cpp.cond]

这是在对 进行宏替换expr、将其标识符(和关键字)替换为0、将其preprocessing-tokens转换为tokensdefined对运算符求值等之后完成的。

tokens我的问题是,当其中之一expr是 a 时会发生什么user-defined-literal

该程序格式不正确。

我的论点的核心是从16.1/1脚注中的观察中收集到的,即在翻译阶段 4 中除了宏名称之外147没有其他名称。identifiers

争论:

根据2.14.8 [lex.ext]/2

Auser-defined-literal被视为对 aliteral operator 或 的调用literal operator template (13.5.8)

因此,即使在 中描述的所有替换之后,我们仍然有对(运算符)函数的剩余调用16.1/4。(其他尝试,例如使用constexpr函数,将因用 替换所有非宏而受挫identifiers0

由于这发生在翻译阶段 4,因此还没有定义甚至声明的函数;尝试查找literal-operator-id一定会失败(16.1/1有关类似的论点,请参见脚注 147)。

从稍微不同的角度来看,5.19/2我们发现:

Aconditional-expression是 a,core constant expression除非它涉及以下其中一项作为潜在计算的子表达式 (3.2) [...]:

  • [...]
  • 对文字类或 constexpr 函数的 constexpr 构造函数以外的函数的调用;
  • 调用未定义的 constexpr 函数或未定义的 constexpr 构造函数 [...];

由此看来,user-defined literal在 a 中使用 aconstant expression需要定义constexpr literal operator,这在翻译阶段 4 中又不可用。

海合会拒绝这一点是正确的。