通过C++ 17标准阅读,在我看来,pp-number预处理器和数字文字处理之间存在不一致,例如user-defined-integer-literal,它们被定义为由"上层"语言处理.
例如,pp-number根据预处理器语法正确解析以下内容:
123_e+1
Run Code Online (Sandbox Code Playgroud)
但放在符合C++ 11的代码片段的上下文中,
int operator"" _e(unsigned long long)
{ return 0; }
int test()
{
return 123_e+1;
}
Run Code Online (Sandbox Code Playgroud)
目前的Clang或GCC编译器(我还没有测试过其他编译器)会返回类似这样的错误:
unable to find numeric literal operator 'operator""_e+1'
Run Code Online (Sandbox Code Playgroud)
在那里operator"" _e(...)没有找到,并试图定义operator"" _e+1(...)将是无效的.
似乎这是因为编译器将令牌作为pp-number第一个使用,但是user-defined-integer-literal在解析最终表达式时无法回滚并应用语法规则.
相比之下,以下代码编译正常:
int operator"" _d(unsigned long long)
{ return 0; }
int test()
{
return 0x123_d+1; // doesn't lex as a 'pp-number' because 'sign' can only follow [eEpP]
}
Run Code Online (Sandbox Code Playgroud)
这是标准的正确读数吗?如果是这样,编译器应该处理这个,可以说是罕见的极端案例是否合理?
c++ syntax language-lawyer user-defined-literals c-preprocessor
For a bit of fun, I created a very basic compile-time type-value map class, as follows:
template <typename T, auto V>
struct TypeValuePair { };
template <typename... TypeValuePairs>
struct TypeValueMap
{
struct MapItems : TypeValuePairs... { };
template <typename T, auto V>
static constexpr auto Lookup(TypeValuePair<T, V>*)
{ return V; }
template <auto V, typename T>
static T Lookup(TypeValuePair<T, V>*);
template <typename T>
static constexpr auto ValueFor = Lookup<T>((MapItems*)nullptr);
template <auto V>
using TypeFor = decltype(Lookup<V>((MapItems*)nullptr));
};
Run Code Online (Sandbox Code Playgroud)
to be used …