std :: vector是否将std :: tuple和std :: tuple <std :: tuple>视为相同类型?

时间:2019-01-22 10:30:08

标签: c++ tuples

我有一个这样定义的变量

auto drum = std::make_tuple
          ( std::make_tuple
          ( 0.3f
          , ExampleClass
          , [](ExampleClass& instance) {return instance.eGetter ();}
          )
          );

我希望drum是一个元组。 (即((a, b, c)))。

我还有另一个这样定义的变量

auto base = std::make_tuple
          ( 0.48f
          , ExampleClass
          , [](ExampleClass& instance) {return instance.eGetter ();}
          );

我希望这只是三个元素(即(a, b, c))的元组

我还有一个向量定义如下

std::vector<std::tuple<std::tuple< float
                                 , ExampleClass
                                 , std::function<float (ExampleClass&)>
                                 >>> listOfInstruments;

现在,如果我将drum添加到listOfInstruments,我希望不会出错。

listOfInstruments.push_back(drum);确实是这种情况

listOfInstuments.push_back(base);是我期望出现错误的地方,但是代码可以很好地编译。

由于listOfInstruments的类型为'tuple of tuples',难道不应该仅添加'tuple'引起一些错误?除非()(())std::vector视为相同类型。还是我完全错了,这里还有其他工作吗?

似乎无法弄清楚。

1 个答案:

答案 0 :(得分:32)

在这里,线索和向量大多是红色鲱鱼。有效的方式很简单,就是push_back像任何函数一样,可以对其参数执行隐式转换,如以下工作片段所示:

#include <vector>

struct A { };

struct B {
    B(A const &) { }
};

int main() {
    std::vector<B> v;
    v.push_back(A{});
}

回到元组,我们可以看到它(除其他外)有一个条件明确的构造函数(#2 here),该构造函数引用了要成为元组的成员的条件:

tuple( const Types&... args );

当且仅当所有成员都具有隐式副本构造器时,此构造器才是隐式的(在这种情况下(因为综合构造器确实是隐式的))。这意味着std::tuple<...>可隐式转换为std::tuple<std::tuple<...>>,这就是您要观察的内容。