就时空复杂度而言,以下哪一项是迭代std :: vector的最佳方法,为什么?
方法1:
for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
/* std::cout << *it; ... */
}
Run Code Online (Sandbox Code Playgroud)
方式2:
for(std::vector<int>::size_type i = 0; i != v.size(); i++) {
/* std::cout << v[i]; ... */
}
Run Code Online (Sandbox Code Playgroud)
方式三:
for(size_t i = 0; i != v.size(); i++) {
/* std::cout << v[i]; ... */
}
Run Code Online (Sandbox Code Playgroud)
方式4:
for(auto const& value: a) {
/* std::cout << value; ... */
Run Code Online (Sandbox Code Playgroud) 我发现自己最近越来越多地使用C++ 11,而且过去我会使用迭代器,我现在尽可能使用基于范围的for循环:
std::vector<int> coll(10);
std::generate(coll.begin(), coll.end(), []() { return rand(); } );
Run Code Online (Sandbox Code Playgroud)
C++ 03:
for (std::vector<int>::const_iterator it = coll.begin(); it != coll.end(); ++it) {
foo_func(*it);
}
Run Code Online (Sandbox Code Playgroud)
C++ 11:
for (auto e : coll) { foo_func(e); }
Run Code Online (Sandbox Code Playgroud)
但是,如果集合元素类型是模板参数呢?foo_func()可能会重载以通过const引用传递复杂(=昂贵的复制)类型,并通过值传递简单的类型:
foo_func(const BigType& e) { ... };
foo_func(int e) { ... };
Run Code Online (Sandbox Code Playgroud)
当我使用上面的C++ 03风格的代码时,我没有多想.我会以相同的方式迭代,因为取消引用const_iterator会产生一个const引用,一切都很好.但是使用C++ 11基于范围的for循环,我需要使用const引用循环变量来获得相同的行为:
for (const auto& e : coll) { foo_func(e); }
Run Code Online (Sandbox Code Playgroud)
突然间我不再确定了,如果这auto是一个简单的类型(例如实现引用的幕后指针),这将不会引入不必要的汇编指令.
但是编译示例应用程序确认了简单类型没有开销,这似乎是在模板中使用基于范围的for循环的通用方法.如果不是这种情况,那么boost :: call_traits :: param_type就是这样的.
问题:标准中是否有任何保证?
(我意识到这个问题与基于范围的for循环并不真正相关.当使用const_iterators时它也存在.)
假设我使用基于范围的循环编程时的当前规则说
使用
for(auto const &e :...)或for(auto &e:...)在可能时使用for(auto a: ...).
我以我自己的经验和这个问题为例.
但是在读完关于循环的新简洁之后我想知道,我不应该用我&的规则替换我的规则&&吗?正如这里所写,这看起来像迈耶斯的通用参考.
所以,我问自己,如果我的新规则要么
使用
for(auto const &&e :...)或for(auto &&e:...)在可能的时候......
或者这不总是有效,因此应该是相当复杂的
检查
for(auto const &&e :...)或者for(auto &&e:...)是可能的,再考虑for(auto const &e :...)或者for(auto &e:...),并且只在需要时不使用引用.
是否可以仅使用foreach迭代std :: map中的所有值?
这是我目前的代码:
std::map<float, MyClass*> foo ;
for (map<float, MyClass*>::iterator i = foo.begin() ; i != foo.end() ; i ++ ) {
MyClass *j = i->second ;
j->bar() ;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法可以做到这一点?
for (MyClass* i : /*magic here?*/) {
i->bar() ;
}
Run Code Online (Sandbox Code Playgroud) clang已经开始实现从n3994开始的基于范围的基于for循环.通常在引入基于范围的for循环时,我们会以避免不必要的复制的形式看到代码.似乎n3994提出的在各方面都是优越的.我有几个问题:for (auto & v : vector)for (auto && v : vector)
auto &而不是auto &&后者显然有利?auto &&于破坏现有代码?它会对新代码产生实际影响吗?auto &&吗?有没有一种情况时decltype(auto)会比一个更好的选择auto(可能与&,&&或CV限定符)时,使用基于范围的for循环?换句话说,你会写下面的代码吗?
for (decltype(auto) item : range) {
// ...
}
Run Code Online (Sandbox Code Playgroud) 我或多或少得出的结论是,不可能编写一个符合条件的容器,其value_type没有直接存储在容器中.我认为这是不幸的,因为我经常最终希望我有容器,其中值类型是部分计算或由不连续的部分组装(下面的例子,但与问题没有直接关系).我知道如何编写使用代理对象的迭代器,虽然这很烦人.但我现在想知道这些野兽的C++标准是否确实存在空间.这里可能有太多的措辞; tl; dr版本很简单:§24.2.5的第1段和第6段真正意味着什么,以及违反明显意义的程度会破坏标准算法?或者,换句话说,它们如何被解释为允许代理迭代器?
正如Pete Becker所指出的那样,实际上没有任何东西迫使我的容器符合为标准库容器设定的要求.但是为了使用具有许多标准算法的容器,它必须要么具有至少为a的符合迭代器forward_iterator_tag,或者它必须在于它,但仍然设法满足特定算法对其迭代器施加的操作(如果不是正式的)要求. .
这是我的推理:
表96(§23.2.1),容器要求,包括:
Expression Return type Assertion/note
------------ ------------- ---------------------
X::iterator iterator type any iterator category
whose value that meets the
type is T forward iterator
requirements.
Convertible to
const_iterator.
a.begin() iterator;
const_iterator for
constant a.
Run Code Online (Sandbox Code Playgroud)
现在,转发迭代器:
§24.2.5,第14段.1:
X如果......,类或指针类型满足前向迭代器的要求- 如果
X是一个可变的迭代器,reference是一个引用T; ifX是一个const迭代器,reference是一个引用const T
确实没有直接要求*a返回reference(a类型的地方X).要求是:
从表107(输入迭代器)
*a必须是"可转换为T",如果a是不可引用的.从表106(迭代器)
*r必须有类型reference …
我是 C++ 新手,所以有一个问题。
有C++代码:
class Test
{
public:
std::string name;
Test(){};
Test(std::string name) {
std::cout << "Create " << name << '\n';
Test::name = name;
};
~Test() {std::cout << "Destroy " << name << '\n';}
};
std::vector<Test> test {Test("one"), Test("two"), Test("three")};
void main()
{
for (auto i : test)
std::cout << i.name << '\n';
std::cout << "Clear\n";
test.clear();
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
Create one
Create two
Create three
Destroy three
Destroy two
Destroy one
one
Destroy one
two
Destroy two
three
Destroy …Run Code Online (Sandbox Code Playgroud) 例如,循环:
std::vector<int> vec;
...
for (auto& c : vec) { ... }
Run Code Online (Sandbox Code Playgroud)
将迭代vec并通过引用复制每个元素.
有没有理由这样做?
for (int& c : vec) { ... }
Run Code Online (Sandbox Code Playgroud) 是否可以根据预定义的范围循环向量?
我需要这样的东西:
for(auto& it : myvector[0, 30])
Run Code Online (Sandbox Code Playgroud)
或者:
for(auto& it : myvector[0-30])
Run Code Online (Sandbox Code Playgroud)
这可能吗?我已经尝试了两种方法,但都不起作用。
如何使用不同类型的变量声明和推回向量的二维向量.矢量是一种好方法(使用数组是否更好)?
我的变量是这样的:
int id;
string name;
int start;
int end;
Run Code Online (Sandbox Code Playgroud)
我想获得一个列表:((id1 name1 start1 end1),(id2 name2 start2 end2)...
对不起这个基本问题,但我曾经使用过python,允许这样做.谢谢