用于双参数构造函数的用户定义文字

1.6*_*618 5 c++ operator-overloading user-defined-literals c++11

请考虑以下代码:

#include <iostream>

class Point
{
public:
    int x,y;
    Point(int newx, int newy) : x(newx), y(newy) {}
};

Point operator"" x(const unsigned long long i)
{
    return Point(i, 0);
}

int main()
{
    Point p = 5x;

    std::cout << "\npoint is " << p.x << "," << p.y << "\n\n";

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

UDL有效,但它是否可以使它适用于Point的构造函数的两个参数?例如,3x5是一个文字,Point(3,5)甚至是偶数3.5x,然后在操作员体中做一些数学运算,将整个部分与浮点数的小数部分分开..?

Jer*_*fin 2

首先,请注意您为 UDL 指定的名称必须以下划线开头。

是的,这是可能的,但您是否真的想要这样做可能值得商榷。

Point operator"" _x(long double x) {
    return Point(floor(x), (x-floor(x))*10);
}

int main(){
    auto p = 3.5_x;
}
Run Code Online (Sandbox Code Playgroud)

至于为什么你不愿意。现在,它执行固定乘以 10,将浮点数的小数部分转换为整数。如果你输入类似的内容1.23,你可能会期望y如此23,但这会给2.3相反的结果。

更糟糕的是,您在源代码中给出的数字可能很容易变成二进制的重复数字,因此几乎没有办法从浮点数的小数部分开始并确保您生成最初想要的结果。

以这种方式使用浮点数似乎也缺乏一种合理的方式来表示像 之类的点(3, -5)。输入仅允许用一个符号来表示整个数字。

您可以将其定义为采用字符串,然后在运行时解析该字符串以生成正确的值。

auto p = "3x5"_x;
Run Code Online (Sandbox Code Playgroud)

但大多数人不太喜欢这个选项。必须将输入括在引号中会毁掉一些事情。如果您无论如何都想这样做,代码将如下所示:

Point operator"" _x(char const * const s, unsigned long long len) {
    int x, y;
    sscanf(s, "%dx%d", &x, &y);
    return Point(x, y);
}
Run Code Online (Sandbox Code Playgroud)

当然,您可能更喜欢使用sscanf. 我只是快速地将其组合在一起以显示语法,而不是作为字符串解析的教程。