我通常以这种方式迭代一个向量:
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++ 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意味着你与拥有副本的所有东西共享所有权). …我想找到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) 假设我有一个函数将数据导入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++的新手,我正在尝试制作一个小地牢爬虫游戏.目前我在头文件中声明了多个向量,但它们似乎给出了多个错误.我试过在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) 考虑以下代码:
#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++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) 假设我有一个std :: vector,我通过某种方式获得了第n个元素的地址.给定我的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++ 和 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)