使用统一初始化 初始化二维向量

Posted

技术标签:

【中文标题】使用统一初始化 初始化二维向量【英文标题】:initializing 2d vector using uniform initialization 使用统一初始化 初始化二维向量 【发布时间】:2018-11-26 19:05:04 【问题描述】:

如何添加功能来初始化这个 2dvector 类:-

template <typename T>
class uvector2d 

public:
uvector2d(size_t xAxis=0, size_t yAxis=0, T const & 
t=T()) : xAxis(xAxis), yAxis(yAxis), data(xAxis*yAxis, t)  


T & operator()(size_t xNum, size_t yNum) 
return data[xNum*yAxis+yNum];
T const & operator()(size_t xNum, size_t yNum)    
const      return data[xNum*yAxis+yNum];
private:
size_t xAxis,yAxis;
uvector<T> data; 
;

使用统一初始化如下图:-

vector<vector<int> > vect  1, 2, 3 , 
                            4, 5, 6 , 
                            7, 8, 9  ; 

我目前正在使用类似的东西: uvector2dvect(3,3); vect(1,1)=10864;

【问题讨论】:

定义一个具有std::initializer_list&lt;std::initializer_list&lt;T&gt;&gt;类型参数的构造函数,并将其元素复制到data中。 @DanielLangr 答案部分如下 ;) @NathanOliver 我认为答案应该更加详细,并解释为什么某些东西可以作为解决方案。我现在没有时间写它,所以我只是快速提示一下作为评论:)。 @DanielLangr 嗨,我创建了这个 cuvector2d(initializer_list> values); 但无法复制到数据。你能输入代码吗,真的很有帮助吗 【参考方案1】:

你应该实现一个构造器,它接受初始化器列表的初始化器列表作为参数:

uvector2d(std::initializer_list<std::initializer_list<T>> list);

在此构造函数中,您只需将列表元素复制到一维data 成员向量中。

uvector2d(std::initializer_list<std::initializer_list<T>> list)
    : xAxis(list.size()), yAxis(list.begin()->size()) 
  data.reserve(xAxis * yAxis);
  for (const auto& inner_list : list)
    for (const auto& element : inner_list);
      data.push_back(element);

请注意,这仅在内部列表具有 相同大小 时才有效(这是唯一有意义的情况)。此外,您在 2D 向量中的元素存储似乎是 column-major,所以我想初始化器代表一个列列表。如果它实际上是一个行列表,那么你需要转置:

uvector2d(std::initializer_list<std::initializer_list<T>> list)
    : yAxis(list.size()), xAxis(list.begin()->size()) 
  data.resize(xAxis * yAxis);
  size_t y = 0;
  for (const auto& inner_list : list) 
    size_t x = 0;
    for (const auto& element : inner_list); 
      data[x * yAxis + y] = element;
      x++;
    
    y++;
  

我无法使用uvector 尝试此代码,因此如果出现任何问题,请报告。

【讨论】:

是的,丹尼尔它不起作用,所以供您参考,我上传了 uvector 的所有代码以及我做了什么github.com/anu-ShOcKwAvE/stack-overflow-question @user9318103 你的初始化是错误的,它甚至没有编译。学习一些关于 C++ 的基础知识。您可以使用构造函数参数进行初始化 (3,3)braced-init-list ... ,但不能同时使用两者。此外,[0][1] 元素不能等于 1,[0][0] 元素将等于 1。请注意,我的代码中有错字,请参阅更新后的答案。现场演示:wandbox.org/permlink/AsAZfgjVXy9L84QW 是的,我知道 daniel 它不会编译,但你看我希望你的 vector2d 表现得像这样geeksforgeeks.org/2d-vector-in-cpp-with-user-defined-size 这就是问题的全部意义所在 @user9318103 它有效:wandbox.org/permlink/Q48JAJhnTp4tJBpI。您只是没有通过函数调用运算符而不是索引运算符为维度和访问元素提供size 成员函数。 谢谢丹尼尔。:)【参考方案2】:

简答

你应该std::initializer_list。简而言之,它的功能是扩展许多相同类型的参数。您必须创建新的 c-tor,其参数为 std::initializer_list

简介

从 C++11 开始,我们有了新的对象初始化方式:

int x(0);    // old way, rarely used
int y = 0;   // old way, most common
int z 0 ;  // new way, bracing initialization

支撑初始化也称为统一初始化。有关此主题的更多信息,我将向您推荐 Effective Modern C++ - 正是第 7 点。

支撑初始化使用std::initializer_list 进行强类型化(与auto 相同的情况。这就是您使用时的原因:

vector<vector<int> > vect  1, 2, 3 , 
                            4, 5, 6 , 
                            7, 8, 9  ;

你使用std::initializer_list获得了向量的构造函数:

vector( std::initializer_list<T> init, 
        const Allocator& alloc = Allocator() );

回答

现在,如果我们知道括号初始化是如何工作的,我们就知道如果我们有任何带有std::initializer_list 的 c-tor,那么如果可以的话,它将被调用。举例说明如何做到这一点:

class ThreeNumbers

    int x;
    int y;
    int z;
public:
    ThreeNumbers(std::initializer_list<int> list)
    
        std::initializer_list<int>::iterator it = list.begin();
        x = *it++;
        y = *it++;
        z = *it;
    
;

【讨论】:

以上是关于使用统一初始化 初始化二维向量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中使用构造函数初始化二维向量?

c++ 用新类初始化二维向量;默认值更改

在构造函数中初始化成员变量二维向量

如何初始化包含 opencv:matrices 的二维向量?

类中的错误二维向量类初始化

向量中不同类型的统一初始化行为不同