无法从委派构造函数的初始化列表中初始化向量

问题描述

我有一个MyClass类,如下所示:

class MyClass {
public:
    MyClass(vector<vector<float>> arg) {
       // some code here
    }
    MyClass(std::initializer_list<std::initializer_list<float>> arg)
        : MyClass(vector<vector<float>>(arg)) {
    }
    // other class members
};

我试图在上面使用委托的构造函数,因为我希望从MyClassstd::initializer_list<std::initializer_list<float>>类型构造vector<vector<float>>的实例,并且构造函数代码块是相同的。因此,我试图通过初始化多维向量并使用其构造函数来委派嵌套初始化列表的构造。

但是,上面的代码给了我一个编译器错误

no instance of constructor "std::__1::vector<_Tp,_Allocator>::vector [with _Tp=std::__1::vector<float,std::__1::allocator<float>>,_Allocator=std::__1::allocator<std::__1::vector<float,std::__1::allocator<float>>>]" matches the argument list -- argument types are: (std::initializer_list<std::initializer_list<float>>)
In file included from /opt/wandBox/gcc-9.3.0/include/c++/9.3.0/vector:67,from prog.cc:11:
/opt/wandBox/gcc-9.3.0/include/c++/9.3.0/bits/stl_vector.h:622:7: note: candidate: 'std::vector<_Tp,_Alloc>::vector(std::initializer_list<_Tp>,const allocator_type&) [with _Tp = std::vector<float>; _Alloc = std::allocator<std::vector<float> >; std::vector<_Tp,_Alloc>::allocator_type = std::allocator<std::vector<float> >]'
  622 |       vector(initializer_list<value_type> __l,|       ^~~~~~
/opt/wandBox/gcc-9.3.0/include/c++/9.3.0/bits/stl_vector.h:622:43: note:   no kNown conversion for argument 1 from 'initializer_list<std::initializer_list<float>>' to 'initializer_list<std::vector<float>>'
  622 |       vector(initializer_list<value_type> __l,|              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~

我在做什么错了?

解决方法

std::vector的initializer_list构造函数如下:

vector(std::initializer_list<value_type>)

value_typestd::vector的第一个模板参数。在这种情况下,std::vector<std::vector<float>>具有value_type = std::vector<float> -这意味着它只能直接由std::initializer_list<std::vector<float>>构造。

要使其正常运行,您将需要通过以下方式之一进行更新:

  1. 将您的std::initializer_list更新为std::initializer_list<std::vector<float>>
  2. 只使用std::vector<std::vector<float>>构造函数,而完全不使用initializer_list 1
  3. 从构造器中的initializer_list<initializer_list<float>>开始的范围构造:
    MyClass(std::initializer_list<std::initializer_list<float>> arg)
        : vec{arg.begin(),arg.end()} 
    {
        // each iterator points to an initializer_list,which implicitly
        // constructs each vector
    }
    
    编辑:由于此问题是针对委托构造函数的,因此您将不得不首先明确地构造一个临时的向量载体:
    MyClass(std::initializer_list<std::initializer_list<float>> arg)
      : MyClass{std::vector<std::vector<float>>{arg.begin(),arg.end()}} 
    
    在这种情况下,委派构造函数可能不是解决问题的最佳方法。参见下文。

1 由于std::vector已经可以与初始值设定项列表一起正常使用,即使嵌套在其他类型中,也可能最简单的方法是完全忽略添加显式的std::initializer_list构造器- -并且只需在实现中正确使用移动语义即可。

如果您正确使用std::move,则此构造函数无论如何应该相对便宜-这可以免费提供初始化列表功能。

,

您需要floatsstd::initializer_list的向量;

我相信这就是您要寻找的

class MyClass{
        public:
            MyClass(vector<vector<float>> arg ): vec( arg) {
                // some code here
            }
            MyClass(std::initializer_list<std::vector<float>> arg) 
            : vec( arg ) {}; 
            
            // other class members

        private:
            std::vector<vector<float>> vec;
};