5

次のコードを検討してください。

#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 のコンストラクターの両方の引数に対して機能させることは可能ですか? たとえば3x5、リテラルPoint(3,5)または場合3.5xによっては、演算子本体で数学を実行して、フロートの小数部分から全体の部分を分離します..?

4

2 に答える 2

2

まず、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、おそらく になると予想さyれますが23、これは代わりに与えられ2.3ます。

さらに悪いことに、ソース コードで指定した数値は簡単に 2 進数の繰り返し数値に変わる可能性があるため、浮動小数点数の小数部分から開始して、当初意図したものを生成していることを確認する方法はほとんどありません。

このように浮動小数点数を使用すると、 のような点を表す合理的な方法が欠けているようにも見え(3, -5)ます。入力では、数値全体に対して 1 つの符号のみが許可されます。

代わりに文字列を受け取るように定義し、実行時に文字列を解析して正しい値を生成することができます。

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。文字列解析のチュートリアルとしてではなく、構文を示すためにこれを簡単にまとめただけです。

于 2014-02-24T19:54:04.443 に答える
1

たぶん、任意の演算子をオーバーロードすることによって:

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);ですか?

于 2014-02-24T19:49:54.300 に答える