问题 使用用户定义的文字成员时编译错误


编译此代码时(没有任何标题)

template <typename T>
struct Temperature {
    T temp;

    explicit Temperature(T t)
        : temp(t)
    {}
};

Temperature<long double> operator "" _f (long double t)
{
    return Temperature<long double>((t - 32) / 1.8);
}

int main()
{
    auto t = 100.0_f;
    t.temp;

    100.0_f.temp; // ERROR AT THIS LINE
    return 0;
}

编译器(Ubuntu 14.04上的g ++ 4.8和clang ++ 3.4)都会抱怨

error: unable to find numeric literal operator ‘operator"" _f.temp’
     100.0_f.temp;
     ^

好像是 _f.temp 被认为是那里的后缀。为什么编译器会这样解析它,而不是停留在点?


3058
2018-06-29 05:57


起源

最大的蒙克。 100.0_f.temp 是有效的 PP-数 令牌。 - T.C.
改成 (100.0_f).temp - Mine
@ T.C。不知道pp-number标记可能包含多个点。你能用这样的形式给我看一个例子吗? - neuront
@ T.C。 [lex.pptoken] / 1似乎暗示了这一点 100.0_f.temp 没有通过预处理阶段? - M.M
@ M.M当然,它无法转换为令牌,因此该程序格式错误。 - T.C.


答案:


预处理数字 是奇怪的野兽,主要用于使预处理器更容易编写。

pp-number:
    digit
    . digit
    pp-number digit
    pp-number identifier-nondigit
    pp-number ' digit
    pp-number ' nondigit
    pp-number e sign
    pp-number E sign
    pp-number p sign
    pp-number P sign
    pp-number .

12 是有效的 PP-数 令牌,也是 0xe+foo (参见[lex.pptoken] / 4中的例子),等等 .12.CA'TS_RULE..56.me+owp-urr。如果后两个使它超过翻译阶段6,则程序格式不正确,因为它在阶段7中无法转换为有效令牌。在此之前,它是有效的,因此最大的munch说我们解析 0xe+foo 要么 100.0_f.temp 作为单个预处理令牌。


16
2018-06-29 07:21



真是野兽。希望标准提供更新,使代码更容易编写。 - neuront
我永远不会想到 0xe+foo 可能是无效的C ++,这似乎错了...... - Holt