新功能' C ++中的语法

时间:2014-10-29 10:51:43

标签: c++

我是一名程序员,在进行更改并学会避免STL时学习了C ++。相反,我使用了MFC容器类和我可能正在使用的框架可用的任何容器类。

我也从未真正使用智能指针。 8)

所以,我正在研究C ++中的新功能(使用VS 2013)

以下编译并正常工作:

vector<string> names;
names.push_back("tom");
names.push_back("dick");
names.push_back("harry");
names.push_back("bob");
names.push_back("percy");
names.push_back("freddie");
names.push_back("sam");

for (auto name : names)
{
    cout << "Name: " << name << endl;
}

以下内容不是:

vector<unique_ptr<Thing>> things;
things.push_back(unique_ptr<Thing>(new Thing("tom", 23)));
things.push_back(unique_ptr<Thing>(new Thing("dick", 26)));
things.push_back(unique_ptr<Thing>(new Thing("harry", 33)));
things.push_back(unique_ptr<Thing>(new Thing("fred", 43)));
things.push_back(unique_ptr<Thing>(new Thing("bob", 53)));

for (auto thing : things)
{

}

我收到以下错误消息:

1>c:\dev\src\samples\consoletest\consoletest\vectorstuff.cpp(34): error C2280: 'std::unique_ptr<Thing,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function
1>          with
1>          [
1>              _Ty=Thing
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(1486) : see declaration of 'std::unique_ptr<Thing,std::default_delete<_Ty>>::unique_ptr'
1>          with
1>          [
1>              _Ty=Thing
1>          ]

所以我尝试了标准迭代器:

for (auto thing = things.begin(); thing != things.end(); ++thing)
{
    cout << "Name: " << (*thing)->getName() << " age: " << (*thing)->getAge() << endl;
}
编译好的

,为什么for(auto thing:things)语法不起作用?

这是我对Thing的定义:

class Thing
{
public:
    Thing();
    Thing(const Thing& original);
    Thing(const std::string& name, int age);

    const std::string& getName() const { return name; }
    int getAge() const { return age; }

private:
    std::string name;
    int age;
};

和代码:

Thing::Thing() : name(""), age(21)
{
}

Thing::Thing(const Thing& original) : name(original.name), age(original.age)
{
}

Thing::Thing(const std::string& name, int age) : 
    name(name),
    age(age)
{
}

我添加了默认构造函数和复制构造函数,但仍然获取了已删除的函数。

4 个答案:

答案 0 :(得分:8)

auto thing : things按值复制,对unique_ptr禁用。而是使用:

auto &thing : things

这种情况与基于迭代器的循环之间的区别在于,在这种情况下,auto thing是根据auto thing = *begin;see here更多信息)定义的。{/ p >

但是在你编写auto thing = things.begin();的情况下,thing实际上是一个迭代器,所以一切都很好。

答案 1 :(得分:7)

auto thing : things表示每次迭代中thing的值是things元素的副本。如果类型不可复制(因为unique_ptr不是),那么这将不起作用。

相反,请将thing作为参考:

for (auto & thing : things)   // add "const" if appropriate

答案 2 :(得分:2)

在某些情况下(例如,如果things恰好是vector<bool>),for (auto& thing : things)将无法编译。更通用的方法是使用

for (auto&& thing : things)

这是C++17 terse range-based for loopsfor (thing : things))隐式使用的语法,因此您可以立即开始习惯它。

答案 3 :(得分:1)

除了使用

for (auto & thing : things)

要访问您的对象而不是副本,请考虑以下事项:

things.push_back(unique_ptr<Thing>(new Thing("tom", 23)));

这会在堆上创建一个新的Thing,并将指向它的指针推送到向量things中。 为什么不简单地将Thing存储在things中并让向量处理所有内存?

things.push_back(Thing("tom", 23);