使用fold表达式构造一个普通的对象

时间:2018-03-10 20:24:23

标签: c++ constructor tuples c++17 fold

我正在尝试使用std::apply和折叠表达式构造一个对象。从我在线阅读文档可以看出,折叠逗号应该可行。这是一个澄清的例子。

struct my_pair final {
    float x;
    float y;
};

struct test final {
    my_pair back() {
        return std::apply(
                [](auto&... vector) {
                    return my_pair{ (vector.back(), ...) }; },
                data);
    }

    std::tuple<std::vector<float>, std::vector<float>> data
            = { { 0.f }, { 1.f } };
};

我解压缩元组,获取最后的元素并尝试使用元素返回一个新对象。

各种编译器抱怨y从未初始化。不知何故,扩张并未发生。至少,不是我期望的。

error: missing field
      'y' initializer [-Werror,-Wmissing-field-initializers]
  ...[](auto&... vector) { return my_pair{ (vector.back(), ...) }; },
                                                                ^

如果我禁用-Werror,则my_pair的第一个值为1,第二个值为0.我尝试使用一元左折,但结果相同。

看起来这应该可行,cppreference有这个矢量push_back示例,看起来很相似(从我的角度来看)。

template<typename T, typename... Args>
void push_back_vec(std::vector<T>& v, Args&&... args)
{
    (v.push_back(args), ...);
}

是否可以使用折叠表达式创建一个简单(pod)类型的对象?如果是这样,从一个解包的元组?

1 个答案:

答案 0 :(得分:9)

这里你不需要折叠表达。正确的代码是:

[](auto&... vector) 
{
    return my_pair{vector.back()...}; 
}

使用现有代码,这是发生的扩展:

return my_pair{ (0.f, 1.f) }

使用(0.f, 1.f)初始化的第一个元素,其值为1.f。在这种情况下,逗号标记是逗号运算符 - 它不会在聚合初始化期间分离参数。