标签: stdvector

迭代向量的元素时,索引类型应该是什么?

我通常以这种方式迭代一个向量:

for (int i = 0; i < myVector.size(); i++) {
    Element* e = myVector[i];
}
Run Code Online (Sandbox Code Playgroud)

但是编译器通常会给我这个警告:

warning: C4018: '<' : signed/unsigned mismatch
Run Code Online (Sandbox Code Playgroud)

所以,如果a int不正确,索引应该是哪种类型?vector :: size()似乎是"size_type"类型,但我宁愿使用更有意义的类型.有什么建议吗?

c++ indexing types loops stdvector

10
推荐指数
1
解决办法
7212
查看次数

unique_ptr的临时只读副本

我对C++ 11的智能指针很陌生,我正试图在项目中有效地使用它们.在我的项目,我有很多的需要常量引用一个功能vector的unique_ptr,做一些关于它的计算,并把一些成果在返回参数,如下所示:

void computeCoefficients(const vector<unique_ptr<Scalar>>& roots, 
    vector<unique_ptr<Scalar>>& coeffs) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

我正在使用,unique_ptr因为调用所有这些函数的过程是对象的唯一所有者vector,而函数只是"借用"对象以便将它们作为输入读取.

现在我正在尝试编写一个函数,在vector它接收的不同子集上进行计算,为了做到这一点,它需要有不同的"版本" vector包含这些子集,以便传递到另一个函数,vector<unique_ptr<Scalar>>作为输入.但获取向量子集的唯一方法是复制它 - 这是一个问题,因为unique_ptrs无法复制.我希望代码看起来像这样:

void computeOnSet(const vector<unique_ptr<Scalar>>& set, unique_ptr<Scalar>& output) {  
    ...
}

void computeOnAllSubsets(const vector<unique_ptr<Scalar>>& set, vector<unique_ptr<Scalar>>& outputs) {
    for(int i = 0; i < input.size(); i++) {
        auto subset = vector<unique_ptr<Scalar>>(set.begin(), set.begin()+i);
        subset.insert(subset.end(), set.begin()+i+1, set.end();
        computeOnSubset(subset, outputs.at(i));
    }
}
Run Code Online (Sandbox Code Playgroud)

当然这不起作用.如果我用unique_ptrs 代替s,我可以使它工作shared_ptr,但这有两个问题:

  • 它在哲学上意味着我与该computeOnSubsets功能共享该组的所有权,而我不是; 呼叫者仍然是唯一的所有者.(我读到这shared_ptr意味着你与拥有副本的所有东西共享所有权). …

c++ shared-ptr stdvector unique-ptr c++11

10
推荐指数
1
解决办法
3343
查看次数

具有lambda的对的向量的lower_bound

我想找到std::lower_bound的一个的std::vector的std::pair根据的第二与拉姆达元素.

std::vector < std::pair <int, double> > vec;
vec.resize(5);

auto it = std::lower_bound(vec.begin(), vec.end(), lambda);
// what is that lambda here?
Run Code Online (Sandbox Code Playgroud)

c++ lambda stdvector std-pair

10
推荐指数
2
解决办法
1万
查看次数

在不释放内存的情况下销毁std :: vector

假设我有一个函数将数据导入std向量:

void getData(std::vector<int> &toBeFilled) {
  // Push data into "toBeFilled"
}
Run Code Online (Sandbox Code Playgroud)

现在我想将这些数据发送到另一个函数,该函数应在完成时释放数据:

void useData(int* data)
{
  // Do something with the data...
  delete[] data;
}
Run Code Online (Sandbox Code Playgroud)

这两个函数(getData和useData)都是固定的,无法更改.复制数据一次时这很好用:

{
  std::vector<int> data;
  getData(data);
  int *heapData = new int[data.size()];
  memcpy(heapData, data.data(), data.size()*sizeof(int));
  useData(heapData);
  data.clear();
}
Run Code Online (Sandbox Code Playgroud)

但是,这个memcpy操作很昂贵而且并不是真正需要的,因为数据已经在堆上了.是否可以直接提取和使用std向量分配的数据?像(伪代码)的东西:

{
  std::vector<int> data;
  getData(data);
  useData(data.data());
  data.clearNoDelete();
}
Run Code Online (Sandbox Code Playgroud)

编辑:

这个例子可能没有多大意义,因为在函数调用useData之后可以释放向量.但是,在实际代码中,useData不是一个函数,而是一个接收数据的类,这个类的寿命比向量长...

c++ vector std stdvector c++11

10
推荐指数
2
解决办法
2387
查看次数

ERROR C2039:'vector':不是'std'的成员

我是C++的新手,我正在尝试制作一个小地牢爬虫游戏.目前我在头文件中声明了多个向量,但它们似乎给出了多个错误.我试过在StackOverflow上搜索这个问题,但答案似乎并没有起作用.

这是我的一个头文件:(Hero.h)

#pragma once

class Hero {
public:
    Hero();
    std::string name;
    int experience;
    int neededExperience;
    int health;
    int strength;
    int level;
    int speed;
    std::vector<Item> items = std::vector<Item>();
    void levelUp();
private:
};
Run Code Online (Sandbox Code Playgroud)

这是我的.cpp文件:(Hero.cpp)

#include "stdafx.h"
#include <vector>
#include "Hero.h"
#include "Item.h"

Hero::Hero() {

}
void Hero::levelUp()
{

};
Run Code Online (Sandbox Code Playgroud)

就像我说我是C++的新手,所以我的代码可能比我知道的更多错.这只是一个考验.

以下是Visual Studio 2015的错误列表中显示的错误:

Error   C2039   'vector': is not a member of 'std'  CPPAssessment   hero.h  13  
Error   C2143   syntax error: missing ';' before '<'    CPPAssessment   hero.h  13  
Error   C4430   missing type specifier - …
Run Code Online (Sandbox Code Playgroud)

c++ stdvector visual-studio c++11

10
推荐指数
2
解决办法
2万
查看次数

C ++ std :: vector initializer_list重载歧义(g ++ / clang ++)

考虑以下代码:

#include <vector>

#define BROKEN

class Var {
public:
#ifdef BROKEN
    template <typename T>
    Var(T x) : value(x) {}
#else
    Var(int x) : value(x) {}
#endif

    int value;
};

class Class {
public:
    Class(std::vector<Var> arg) : v{arg} {}

    std::vector<Var> v;
};
Run Code Online (Sandbox Code Playgroud)

不管是否BROKEN定义,Clang ++(7.0.1)都会编译此错误,而如果BROKEN已定义,则g ++(8.2.1)会引发错误:

main.cpp:9:20: error: cannot convert ‘std::vector<Var>’ to ‘int’ in initialization
  Var(T x) : value(x) {}
                    ^
Run Code Online (Sandbox Code Playgroud)

据我所知,std::vector(std::vector&&)在两种情况下,这里使用的统一初始化都应选择构造函数。但是,显然,g++它将{arg}视为初始化列表,并尝试初始化应用于向量的vwith 的第一个元素Var,这将不起作用。

如果BROKEN未定义,则g ++显然足够聪明,可以意识到initializer_list重载将无法正常工作。

哪个是正确的行为,或者标准都允许? …

c++ stdvector initializer-list uniform-initialization

10
推荐指数
1
解决办法
192
查看次数

从立即函数返回 std::vector

从 C++20 开始,std::vector可以在常量表达式中使用。据我所知,当前的 C++ 允许动态分配内存,条件是任何此类分配在常量表达式“结束”时都被释放。

但是,我遇到的情况是,在立即运行的情况下,规则可能会有所不同。请考虑以下示例:

consteval auto getVec() {
    return std::vector<int>(9);
}

static_assert( getVec().size() == 9 );
Run Code Online (Sandbox Code Playgroud)

这里立即consteval函数getVec返回 not-empty std::vector,其大小在常量表达式中验证。

我期望这段代码能够编译,因为所有释放都必须自动完成,并且实际上它在 Clang 中被接受libc++。

但 MSVC 抱怨道:

error C7595: 'getVec': call to immediate function is not a constant expression
note: (sub-)object points to memory which was heap allocated during constant evaluation
fatal error C1903: unable to recover from previous error(s); stopping compilation
Run Code Online (Sandbox Code Playgroud)

GCC 的行为类似:

error: 'getVec()()' is not a constant expression …
Run Code Online (Sandbox Code Playgroud)

c++ stdvector language-lawyer c++20 consteval

10
推荐指数
1
解决办法
600
查看次数

获取给定其地址的std :: vector元素的索引

假设我有一个std :: vector,我通过某种方式获得了第n个元素的地址.给定我的std :: vector的基地址,是否有一种简单的方法(比迭代迭代更快)来获得元素出现的索引?让我们假设我确定元素在向量中.

c++ stl stdvector

9
推荐指数
2
解决办法
6144
查看次数

std :: vector的一个小问题,并在循环时更改集合

此循环在运行时更改迭代器:

std::vector<int> c;
c.push_back(1);
c.push_back(2);

std::vector<int>::iterator iter    = c.begin();
std::vector<int>::iterator endIter = c.end();

while( iter != endIter )
{
    std::cout << (*iter) << std::endl;
    iter = c.erase(iter);
}
Run Code Online (Sandbox Code Playgroud)

它不起作用,因为:

对迭代元素及其与容器末尾之间的元素的迭代器和引用无效.过去的迭代器也是无效的

我怎样才能重写这个(不使用std::list和使用while循环)?

顺便说一句,我知道auto自C++ 11以来已经实现了.使用它为什么有益?

c++ stdvector

9
推荐指数
3
解决办法
506
查看次数

如何包装 std::vector 以在纯 C 中使用

在我的项目中,我想使用 C++ 和 STL 容器,但有一个问题,我必须包含用 ANSI C 编写的包含 C++ 的硬件供应商标头(并链接供应商库并使用一些还包括供应商标头的供应商 C 源)保留关键字,例如:vendor.h:

// Vendor header (read only)
    struct Vendor_Export_Struct {
    unsigned char* data;
};

struct Vendor_Export_Struct export; // <<<  compilation error under C++
union Vendor_Union {
    struct Vendor_Export_Struct export; // <<<  compilation error under C++
};
Run Code Online (Sandbox Code Playgroud)

包含在 C++ 中的内容将在编译期间导致错误:在“导出”之前预期不合格的 id。所以我被迫使用纯 C 并考虑是否可以简单地将 STL 向量包装成这样的 C API(后面有 C++ 实现):

cvect.h :

typedef void* Vect_Type;
typedef void** Vect_Iterator_Type;
typedef void* Vect_Data_Type;

Vect_Type Vect_New();
void Vect_PushBack(Vect_Type v, Vect_Data_Type d);
Vect_Iterator_Type Vect_Begin(Vect_Type v);
Vect_Iterator_Type …
Run Code Online (Sandbox Code Playgroud)

c c++ iterator stdvector

9
推荐指数
1
解决办法
476
查看次数