【发布时间】:2016-02-11 23:18:59
【问题描述】:
成员初始化器列表中能否从函数获取的元组中初始化多个成员?
随着通过元组返回多个值变得越来越流行,我希望有一个解决方案。除了语言限制之外,我认为这不可能。
这是我所拥有的 mcve:
auto new_foo(std::size_t size) -> std::tuple<std::unique_ptr<char[]>, int*>
{
auto buffer = std::make_unique<char[]>(size * sizeof(int) + 8);
auto begin = static_cast<int*>(static_cast<void*>(buffer.get() + 4));
return std::make_tuple(std::move(buffer), begin);
}
struct X {
std::unique_ptr<char[]> buffer_{nullptr};
int* begin_{nullptr};
std::size_t size_{0};
X(std::size_t size) : size_{size}
{
std::tie(buffer_, begin_) = new_foo(size);
}
};
这样可以吗?:
X(std::size_t size)
: buffer_{ ??? },
begin_{ ??? },
size_{size}
{
}
我根本无法为每个成员初始化调用一次new_foo(因为它每次调用都会返回另一个元组)。所以
X(std::size_t size)
: buffer_{std:get<0>(new_foo(size)},
begin_{std:get<1>(new_foo(size)},
size_{size}
{
}
这是不可能的(即使不是这样,多次调用以获得相同的结果也不是最优的)
我想到的另一个解决方案是将成员作为元组保存。我放弃了它,因为我需要在类中正确命名的两个成员,而不是使用 get<0> 和 get<1> 访问。
另一种解决方法是创建一个简单的单独结构来保存这两个成员。这样他们就有了名字,但是添加了另一个级别的限定符,并且可能我必须为它创建一个复制ctor(因为unique_ptr)。
据报道,hereC++1z 将具有 结构化绑定 (D0144R0),这将使这成为可能:
auto {x,y,z} = f();
由于我没有找到完整的论文,我不知道这是否有助于成员初始化列表。我怀疑不是。
【问题讨论】:
标签: c++ tuples c++14 c++17 initialization-list