C++20 在三元语句中返回一个元组 [duplicate]

C++20 return a tuple in ternary statement [duplicate]

提问人:Ξένη Γήινος 提问时间:9/13/2023 最后编辑:BarryΞένη Γήινος 更新时间:9/13/2023 访问量:75

问:

我有一个小函数,它返回三个值。我使用 a 来促进多个值的返回。std::tuple

函数返回的内容由一个变量决定,如果变量不为零,则返回一个元组,否则返回另一个元组。因为我使用 C++20,所以我只使用大括号 () 来构建元组。{}

我认为使用三元语句是完美的,但以下方法不起作用:

#include <tuple>

using std::tuple;

double hue(double b, double g, double r, double d, double i);

tuple<double, double, double> HSL_pixel(double b, double g, double r, double i, double x, double z) {
    double s = x + z;
    double d = z - x;
    double avg = s / 2;
    return d ? {hue(b, g, r, d, i), d / (1 - abs(s - 1)), avg} : {0.0, 0.0, avg};
}

在 Visual Studio 2022 中,在第一个左大括号位置检测到错误,它说:“预期表达式”。

更改为 if else 语句解决了该问题:

tuple<double, double, double> HSL_pixel(double b, double g, double r, double i, double x, double z) {
    double s = x + z;
    double d = z - x;
    double avg = s / 2;
    if (d) {
        return { hue(b, g, r, d, i), d / (1 - abs(s - 1)), avg };
    } 
    else {
        return { 0.0, 0.0, avg };
    }
}

但我想使用三元。在这种情况下,如何使用三元?

C++ C++20 条件运算符 三元标准

评论

0赞 Some programmer dude 9/13/2023
什么?它返回什么?hue
2赞 Pepijn Kramer 9/13/2023
旁注:3 个浮点数的元组不是强颜色类型。只需声明你自己的颜色结构:并使用它。这样,您就不会意外地将非颜色的元组传递给只适用于颜色的函数,并且您也获得了可读的红色/绿色/蓝色值。 旨在用于模板库代码中,而不是作为“简单”的出路,以在一些键入时安全struct color_t { float red; float green; float blue; }std::tuple

答:

3赞 Barry 9/13/2023 #1

从语法上讲,不能将 braced-init-list 与条件运算符一起使用。所以这是格式不正确的:

int a = true ? 1 : {};

你必须写这个:

int b = true ? 1 : int{};

在您的示例中,这是:

cond ? tuple{a, b, c} : tuple{d, e, f}

而不是:

cond ? {a, b, c} : {d, e, f}

或者,如果你真的喜欢使用 braced-init-list,那么你必须使用 /(或只是 )。在这一点上只是一个风格选择。ifelseif

0赞 Jan Schultke 9/13/2023 #2

正如@Barry已经指出的那样,braced-init-list 不能作为条件运算符中的两个表达式之一出现。

除了这个问题之外,返回元组也不是一个好主意,因为从函数的签名中不清楚实际含义。你可以通过使用简单的 s 来大大提高代码质量:tuple<double, double, double>struct

struct rgb_color {
    double r, g, b; // note: float precision is almost always sufficient for colors,
                    //       your monitor can only handle 8 or 10 bits anyway
    // define all comparisons
    friend auto operator<=>(const rgb_color&, const rgb_color&) = default;
};

struct hsl_color {
    double h, s, l; // consider using hue, saturation, lightness instead

   friend auto operator<=>(const hsl_color&, const hsl_color&) = default;
};

有了这样的简单功能,你几乎可以获得所有值得关注的功能,代码也变得更加清晰:structstd::tuple

double hue(rgb_color color, double d, double i);

hsl_color HSL_pixel(rgb_color color, double i, double x, double z) {
    double s = x + z;
    double d = z - x;
    double avg = s / 2;
    return d ? hsl_color{hue(color, d, i), d / (1 - abs(s - 1)), avg}
             : hsl_color{0.0, 0.0, avg};
}

我仍然不确定 , 和 是什么意思,但它们可能也值得以某种方式捆绑在一起。dixz