【问题标题】:Incrementally Growing a Tuple增量增长元组
【发布时间】:2016-11-22 11:39:32
【问题描述】:

假设我想以增量方式收集元组(或等效的异构容器)中的数据,即以增量方式向元组添加另一个值(和类型)。

类似这样的东西(名称和语法是组成的):

growable_tuple tup;
tup.push_back(42);
//...
tup.push_back("Hello");
//...
tup.push_back(' ');
//...
tup.push_back("World"s);

static_assert(4 == std::tuple_size<tup::type>::value); // or
assert(4 == tup.size());

我可以使用std::tuple_cat,但我需要将结果复制并存储在每个这样的cat 的不同局部变量中。

我不能使用std::any,因为我不知道包含的类型。 有没有办法提取any的包含类型?

是否有可能有一个单个局部变量来支持这种“插入”,最好不复制?

Hana 有这样的设施吗?

基本上,我想要一个不会擦除类型的异构容器,以便以后可以访问它们。
我还可以假设插入不依赖于运行时(没有运行时循环插入)。
具体来说,我可以手动查看添加到元组的所有类型(和索引)的代码,并使用它来定义我的初始元组。所有数据在编译时都存在。
我想知道如果没有事先手动指定元组类型就没有办法做到这一点。

这样做的一个明显方法是增量序列化数据(例如到 json)并稍后重新解析它,但这似乎有点迂回。

【问题讨论】:

  • 如果预先知道预期类型的​​集合,您可以使用std::variant 对象的容器。
  • 你能用一些伪代码说明你想要什么吗?
  • @Leon:不,我需要一个元组,但我事先不知道类型。我将添加一个示例。
  • 这与语法无关,而与可用信息有关。 growable_tuple 中的元素数量及其类型在编译时是未知的,这是 static_assert 工作所必需的。
  • @W.F.:更多的是混乱,你需要多个本地对象来存储不断增长的元组——每个对象都有一个额外的条目。另外,我不确定是否要移动,因为这意味着您必须从范围内的许多对象中移动,而您不能触摸。

标签: c++ boost-hana


【解决方案1】:

令人惊讶的是,这显然是可能的。

参见HOW TO IMPLEMENT A COMPILE-TIME META-CONTAINER IN C++ 和相关文章。加上更多的语法糖,它应该能够提供 OP 的功能。

working code 的示例如下所示:

int main () {
  using LX = atch::meta_list<class A>;

  LX::push<void, void, void, void> ();
  LX::set<0, class Hello> ();
  LX::set<2, class World> ();
  LX::pop ();

  print_type<LX::value<>> ();
}

输出:
void print_type() [T = atch::type_list&lt;Hello, void, World&gt;]

这比仅将类型附加到列表更强大。
我期待smeta 库的最终发布。

这里有一个关于该技术的additional post

【讨论】:

    【解决方案2】:

    元组是一个类,就像任何其他类一样。一旦声明,它就是那个类。一个

    std::tuple<int, char *>
    

    一旦声明,将永远是std::tuple&lt;int, char *&gt;。 C++ 是一种静态类型语言。每个对象的类型都已声明,并且是已知的。一旦一个对象是 std::tuple&lt;int, char *&gt; 这就是它的样子,它就不能以某种方式变成 std::tuple&lt;int, char *, char *&gt;

    使用 C++17,可以通过使用 a

    来实现类似的功能
    std::vector<std::any>
    

    any对象的向量,然后将任意对象添加到向量中。此对象的类型将始终为std::vector&lt;std::any&gt;,需要额外的工作来确定向量的每个值是什么。

    【讨论】:

    • 是的,我知道这一切,因此也知道 OP。所有信息在编译时都是已知的,所以我想知道是否例如Hana 有某种类型的擦除(和非擦除)魔法来实现这一点。
    • 没有什么魔法可以改变 C++ 是一种静态类型语言这一基本事实。它就是这样,无论是 hana,任何其他图书馆都无法改变这一点。这就涉及到 C++ 的基本概念。唯一可以做的是std::any 方法。这就是你所能做的。
    猜你喜欢
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    • 2020-01-20
    • 1970-01-01
    相关资源
    最近更新 更多