c ++ 11用户定义的文字,与编译/执行二分法冲突

pax*_*blo 1 c++ user-defined-literals c++11

我知道ISO C标准在分离翻译行为和执行行为方面做了大量工作,部分原因是为了确保交叉编译器不必承载每个目标的执行环境.

这就是说,与正在运行的程序相比,编译器可用的信息有限.这限制了您可以在源代码中执行的操作,例如不基于此函数的返回值初始化变量:

int twice (int val) { return val * 2; }
int xyzzy = twice (7);
int main () { printf ("%d\n", xyzzy); return 0; }
Run Code Online (Sandbox Code Playgroud)

我很好奇的是C++ 11中用户定义的文字如何适合这个方案.由于文字评估依赖于一个函数,所以要阻止该函数执行以下操作:

  • 返回一个随机值(即使基于输入,例如42_roughly给出40到44之间的值)?
  • 有副作用,比如改变全局变量?

是否必须调用函数意味着在编译时计算这些函数并不是真正的文字吗?

如果是这样的话,这些文字比任何其他函数调用的优点是什么.换句话说,为什么:

int xyzzy = 1101_1110_b;
Run Code Online (Sandbox Code Playgroud)

优选:

int xyzzy = makeBin ("1101_1110");
Run Code Online (Sandbox Code Playgroud)

con*_*gus 6

秘诀在于您是否声明用户定义的文字函数constexpr.

比较这个(正常执行时间函数):

#include <iostream>
int operator "" _twice(unsigned long long num) { return num*2; }
int xyzzy = 7_twice;
int main () { std::cout << xyzzy << "\n"; return 0; }
Run Code Online (Sandbox Code Playgroud)

有了这个(编译时常量,static_assert工作):

#include <iostream>
constexpr int operator "" _twice(unsigned long long num) { return num*2; }
int xyzzy = 7_twice;
int main () {
    static_assert(7_twice == 14, "not compile time constant");
    std::cout << xyzzy << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

显然,声明一个函数也constexpr限制了所有语句constexpr,或编译时常量; 没有随机数的恶作剧允许.

  • @paxdiablo:`constexpr`表达式受到严格限制,直到交叉编译器必须能够对它们进行评估.交叉编译器总是能够评估相当复杂的表达式:`int foo [(7/3 == 3)?4:(5> 2?Bar <6> :: baz:2]`必须全部在编译时进行评估`constexpr`主要添加的是_name_某些表达式的能力. (4认同)