【问题标题】:User-Defined Literal for Two-Argument Constructor两参数构造函数的用户定义文字
【发布时间】:2014-02-24 19:33:18
【问题描述】:

请考虑以下代码:

#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;
}

UDL 可以工作,但是是否可以使它对 Point 的构造函数的两个参数都有效?例如3x5Point(3,5) 或什至 3.5x 的文字,然后在运算符主体中进行一些数学运算以将整个部分与浮点数的小数部分分开......?

【问题讨论】:

  • 使用聚合初始化,例如Point p = {3,5}。 IMO 比一些不透明的文字要好得多。
  • @Paranaix 我不知道你能做到这一点!这是 c++11 的新特性吗?
  • @1.618 在一般情况下,是的(就像 UDL 一样);这称为列表初始化。但是如果你从类中删除所有构造函数(这对于这样一个简单的结构可能是明智的),大括号被解释为聚合初始化,从 C++98 开始工作。

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


【解决方案1】:

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

是的,这是可能的,但您是否真的想这样做可能会有疑问。

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

int main(){
    auto p = 3.5_x;
}

至于你为什么不想。现在,这将固定乘以 10 以将浮点数的小数部分转换为整数。如果您输入 1.23 之类的内容,您可能希望 y23,但这将给出 2.3

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

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

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

auto p = "3x5"_x;

不过,大多数人并不是很喜欢这个选项。必须将输入括在引号中会破坏事物。如果你想这样做,代码看起来像这样:

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

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

【讨论】:

  • 谢谢。您的字符串示例是我最初想到的。但现在我知道我可以使用像 {3,5} 这样的初始化程序,我将改为使用它。
【解决方案2】:

也许通过重载一些任意运算符:

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

Point operator&(Point p1, Point p2)
{
     return Point(p1.x, p2.y);
}

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

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

用法:

Point p = 5_x & 42_y;

但是说真的,我认为这样做没有任何意义,至少需要更多的打字。好老的Point(x,y);怎么了?

【讨论】:

  • 重点是k0ln3z 因素需要 C++11 编译器
猜你喜欢
  • 2018-05-22
  • 1970-01-01
  • 2016-02-08
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 2018-10-20
  • 2011-05-19
  • 1970-01-01
相关资源
最近更新 更多