【发布时间】:2015-06-01 10:59:53
【问题描述】:
有没有一种使用std::tie 并一次性创建新变量的好方法?换句话说,如果一个函数返回一个std::tuple,并且我们希望最终将结果分解为单独的组件,有没有办法在不事先定义变量的情况下进行这些赋值?
例如,考虑以下代码:
#include <tuple>
struct Foo {
Foo(int) {}
};
struct Bar{};
std::tuple <Foo,Bar> example() {
return std::make_tuple(Foo(1),Bar());
}
int main() {
auto bar = Bar {};
// Without std::tie
{
auto foo_bar = example();
auto foo = std::get<0>(std::move(foo_bar));
bar = std::get<1>(std::move(foo_bar));
}
// With std::tie
#if 0
{
// Error: no default constructor
Foo foo;
std::tie(foo,bar) = example();
}
#endif
}
基本上,函数example 返回一个元组。我们已经有一个类型为Bar 的变量要赋值给它,但我们需要一个类型为Foo 的新变量。如果没有std::tie,我们不需要创建Foo 的虚拟实例,但是代码要求我们先将所有内容放入std::tuple,然后再进行分割。对于std::tie,我们必须首先分配一个虚拟Foo,但我们没有默认构造函数来执行此操作。真的,我们假装Foo 的构造函数很复杂,所以首先创建一个虚拟值是不可取的。最终,我们只想同时分配给foo 和bar,但希望同时为Foo 分配内存。
【问题讨论】:
-
读到代码我头疼,这肯定表明需要更简单的逻辑。简短的回答是否定的。返回值的元组是一种非常有效的返回和分配方式。 tie:: 只是用来解压值。如果您必须这样做,请考虑绑定到
boost::optional<Foo> -
Bar包含Foo的事实似乎是一个失败的设置。一旦您从Bar中分离(提取)Foo,那 50% 的Bar将变为“有效但可能不确定/未另行指定”。 -
解决将它们分开的需要的一种方法是,用于将
Foo与Bar分开的所有其他类只接受Bar并使用其成员Foo, 或保持Bar活着并传递对Foo的引用。 -
有一个关于这个问题的潜在提案的相关讨论,在这里查看:groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/…
-
因为“内存分配”通常是指动态内存分配,所以我根据变量定义/创建重新表述了这个问题。我可以建议你减少你的例子吗?我认为很多东西是不必要的。我相信你所追求的本质可以归结为something like this。