从 2D 向量创建 1D 向量的函数(错误:表达式必须具有指向对象的指针类型)

Posted

技术标签:

【中文标题】从 2D 向量创建 1D 向量的函数(错误:表达式必须具有指向对象的指针类型)【英文标题】:Function to create 1D-vectors out of 2D-vectors (Error: expression must have pointer-to-object type) 【发布时间】:2020-03-12 14:58:23 【问题描述】:

嗨,我对 C++ 和编程很陌生。我正在尝试制作一个将 2D 向量转换为 1D 单行向量的函数。 不幸的是,我收到错误:“表达式必须具有指向对象的指针类型” 如果我在主函数中键入完全相同的代码而不指定函数,那么它工作正常,如果我想创建一个函数似乎只是不工作。代码如下:

std::vector<float> onelinevector(std::vector<std::vector<float>> invector, int column)

int vsize = (int) invector.size() * column;
std::vector<float> v1d(vsize);
std::cout << "Creating 1D Vector:\n"<< "Inputvector Size: " << invector.size() << "Rows " << column << " Columns" << std::endl;
int k = 0;

for (int i = 0; i<invector.size(); i++) 

    for (int j = 0; j<column ; j++) 
      v1d[k] = invector[i][j];
      k++;
    


return v1d;

这是导致错误的行: v1d[k] = invector[i][j];

我希望你能帮助我。

【问题讨论】:

这个表达式无效:invector[i][j] 因为invector[i] 返回一个float,你不能在它上面调用[] 操作符。 您的代码中没有二维向量?我假设invector 应该是向量的向量? @vahancho 我仍然不明白我想在输入向量的每一行和每一列之间进行迭代并将其分配给新的单行向量 v1d。这就是为什么我使用输入向量的索引并在 for 循环中遍历 for 循环,外部循环用于行,内部循环用于列索引。你能为菜鸟解释一下吗? @emlai invector 应该是二维向量,例如:std::vector inputvector = 1, 2, 3, 4, 5, 6, 7, 8, 9 ; 【参考方案1】:

如果我在主函数中键入完全相同的代码而不指定函数,它可以正常工作

不。你会遇到完全相同的问题。

[...] invector 应该是 2D Vector [...]

不是。 std::vector&lt;float&gt; invectorfloats 的向量,不是任何类型的二维向量。

您会收到错误消息,因为invector[i]floatfloats 没有operator[]

代码中的其他小问题:

不要按值传递大向量。而是通过引用传递以避免不必要的复制。

int vsize = (int) invector.size() * column;

不要使用 c 风格的强制转换 ((int))。如果你想投使用static_cast。虽然你根本不需要在这里投射。用于容器大小的类型是 size_t。它没有签名。 int 已签名,但容器大小不能为负数。实际上,不要通过column。一旦您将 invector 设为 2D,它就会知道其尺寸(见下文),无需将其与向量一起传递。

此外,跟踪索引k 很容易出错,并且不是真正必要的。当写成基于范围的 for 循环时,循环会更容易。

假设所有内部向量的大小相同,并且对您的代码应用的更改最少,它可能如下所示:

using my1Dvector = std::vector<float>;
using my2Dvector = std::vector<my1Dvector>;
my1Dvector onelinevector(const my2Dvector& invector)
    my1Dvector v1d;
    if (invector.size() == 0) return v1d;
    v1d.reserve(invector.size() * invector.front().size());

    for (auto& innervector : invector) 
        for (auto& element : innervector) 
            v1d.push_back(element);
        
    
    return v1d;

最后但同样重要的是,您可以使用insert(参见here),而不是手动推送元素:

my1Dvector onelinevector(const my2Dvector& invector)
    my1Dvector v1d;
    if (invector.size() == 0) return v1d;
    v1d.reserve(invector.size() * invector.front().size());

    for (auto& innervector : invector) 
        v1d.insert(v1d.end(),innervector.begin(),innervector.end());
    
    return v1d;

最后但并非最不重要的一点是,这种转变听起来像是在做不必要的工作。如果您希望将数据存储在平面向量中,则最好首先将其存储在平面向量中。另一方面,您可以将其保留在 2D 向量中,并通过仅转换索引来模拟 1D 访问。

【讨论】:

哇,非常感谢你帮助我并解释它对菜鸟友好!【参考方案2】:

如果您想首先将二维向量转换为一维向量,您需要将二维向量传递给您的函数。 在您的程序中,您尝试逐行添加比这使事情更容易。您有几种方法可以做到这一点,如下所示:

重要的是要注意参数中的'&'。它表示向量是通过引用传递的。没有它,您将不必要地复制整个向量。为了正确起见,我也将其设置为 const。

using namespace std;

vector<float> onelinevectorCStyle(const vector<vector<float>>& invector) 
    vector<float> OneD;

    for (vector<float>::size_type X = 0; X < invector.size(); ++X)
        for (vector<float>::size_type Y = 0; Y < invector[X].size(); ++Y)
                OneD.emplace_back(invector[X][Y]);

    return OneD;


vector<float> onelinevectorCPPIterator(const vector<vector<float>>& invector) 
    vector<float> OneD;

    for (auto X = invector.cbegin(); X != invector.cend(); ++X)
        for (auto Y = (*X).cbegin(); Y != (*X).cend(); ++Y)
            OneD.emplace_back(*Y);

    return OneD;


vector<float> onelinevectorElegantWay(const vector<vector<float>>& invector) 
    vector<float> OneD;

    for (auto& X : invector)
        for (auto& Y : X)
            OneD.emplace_back(Y);

    return OneD;

【讨论】:

非常感谢您的解释,非常感谢!

以上是关于从 2D 向量创建 1D 向量的函数(错误:表达式必须具有指向对象的指针类型)的主要内容,如果未能解决你的问题,请参考以下文章

从 2D 矢量切换到 1D 矢量

值错误:预期的 2D 数组,得到 1D 数组:

如何通过派生类函数从基类更改向量

如何在 C++ 中从现有 2D 向量中创建具有特定列的新向量

在标准向量中将元素分配给 Eigen::Vector2d 会引发错误

c++ 类向量中的段错误