【问题标题】:Why do user-defined string literals and integer literals have different behavior?为什么用户定义的字符串文字和整数文字有不同的行为?
【发布时间】:2018-05-08 02:46:57
【问题描述】:

我正在学习用户定义的文字,但对以下测试代码感到困惑:

std::chrono::seconds operator"" _s(unsigned long long s) {
    return std::chrono::seconds(s);
}

std::string operator"" _str(const char *s, std::size_t len) {
    return std::string(s, len);
}

int main() {
    auto str = "xxxxx"_str;
    std::cout << str.size() << std::endl;    // works

    auto sec = 4_s;
    std::cout << sec.count() << std::endl;   // works

    std::cout << "xxxxx"_str.size() << std::endl;   // works

    std::cout << 4_s.count() << std::endl;   // does **NOT** work!

    return 0;
}

编译器给出以下错误信息:

错误:没有匹配的文字运算符用于调用具有“unsigned long long”或“const char *”类型的参数的“operator”“_s.count”,并且没有匹配的文字运算符模板
cout

似乎它需要 _s.count 作为用户定义的文字。此外,浮点文字的行为类似于整数文字。

为什么用户定义的整数文字和字符串文字有不同的行为?

【问题讨论】:

  • (4_s).count 怎么样?
  • (4_s).count 有效。 ud-suffix 中不能有 ()
  • @for_stack 好像很奇怪,. 也不能在ud-suffix 中使用;无法理解为什么 _s.count 被解析为整个 ud-suffix
  • @songyuanyao 很高兴见到你。能找到解释也就不奇怪了。
  • 4_s.count 被解析为preprocessing number 标记,这是预处理器容忍的,在预处理之后但在句法和语义分析之前是converted to a token,但它不能转换为有效的令牌(例如整数文字或浮动文字),因此违反了[lex.pptoken]/1。诚然,在这种情况下,编译器错误完全没有帮助。

标签: c++ c++11 user-defined-literals


【解决方案1】:

这就是 浮点 字面量的工作原理!!

添加一对括号,它应该可以工作:

std::cout << (4_s).count();

或者,将它们分开(以阻止编译器将其解释为格式错误的小数常量浮点文字):

std::cout << 4_s .count();
//              ^ Space here!

参考:CppReference.com

在上述参考资料的备注部分,

由于最大 munch,用户定义的整数和浮点字面量以 [p, P, (C++17 起)] eE 结尾,后面跟着运算符 @987654329 @ 或-必须在源中用空格与运算符隔开

long double operator""_E(long double);
long double operator""_a(long double);
int operator""_p(unsigned long long);

auto x = 1.0_E+2.0;  // error
auto y = 1.0_a+2.0;  // OK
auto z = 1.0_E +2.0; // OK
auto w = 1_p+2;      // error
auto u = 1_p +2;     // OK

所以说到点,作为小数点,它必须和后面的任何东西分开,否则会被当作浮点数的一部分强>。

我已经从 CppReference 测试了上面的示例,并得到了 非常 类似的错误消息:

test.cpp:19:10: error: unable to find numeric literal
operator 'operator""_E+2.0'
                    ^^^^^^
 auto x = 1.0_E+2.0;  // error

知道_E+2.0 是如何被视为一个整体的ud-suffix


我最初的解释尝试可以在这篇文章的revision history 中找到。

【讨论】:

  • 这个问题不是关于如何让它工作的;这是关于为什么它不起作用。显然,使用字符串和整数时的优先级有所不同,但我相信这个问题的一个好的答案应该可以解释为什么语言是这样设计的。
  • 你在添加CppReference 页面的链接方面击败了我。在您发布和更新您的答案之前,我正在阅读它。
  • @FrancisCugler 我已经添加了它,甚至 我已经阅读了所有内容:)
  • 随着时间的推移,我了解到CppReference 确实是一个出色的资源和存储库,可以作为一个很好的查找表或指南。试图从 MS 那里获得任何有用的信息,这是一个完全不同的故事......
  • @Zefick 什么是全部
猜你喜欢
  • 2013-10-30
  • 2016-05-07
  • 1970-01-01
  • 2010-09-30
  • 2020-09-25
  • 2012-10-18
  • 2010-10-12
  • 1970-01-01
相关资源
最近更新 更多