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

for*_*ack 20 c++ user-defined-literals c++11

我正在学习用户定义的文字,并与以下测试代码混淆:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

错误:没有匹配的文字运算符用于调用'operator'"_ s.count",其参数类型为'unsigned long long'或'const char*',并且没有匹配的文字运算符模板
cout << 4_s.count()<< endl ;

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

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

iBu*_*Bug 18

这就是浮点文字的工作方式!

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

std::cout << (4_s).count();
Run Code Online (Sandbox Code Playgroud)

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

std::cout << 4_s .count();
//              ^ Space here!
Run Code Online (Sandbox Code Playgroud)

参考:CppReference.com

在上面参考的注释部分,

由于最大适合,用户定义的整数和浮点数在结束点的文字[ p,P,(因为C++ 17)] eE,随后当由操作者+-,必须从与空白操作分离在源:

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
Run Code Online (Sandbox Code Playgroud)

因此,当涉及到用作小数点的点时,它必须与后面的任何东西分开,否则它将被视为浮点数的一部分.

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

test.cpp:19:10: error: unable to find numeric literal
operator 'operator""_E+2.0'
                    ^^^^^^
 auto x = 1.0_E+2.0;  // error
Run Code Online (Sandbox Code Playgroud)

明白了如何_E+2.0将整个ud后缀视为一个整体?


我原来的解释尝试可以在这篇文章的修订历史中找到.

  • 这个问题不是关于*如何*使其发挥作用; 它是关于*为什么*它不起作用.显然,使用字符串与整数时优先级有所不同,但我相信这个问题的一个好答案应该可以解释为什么语言是这样设计的. (3认同)