Syntax of new functions in C ++
I am a programmer who learned C ++ while going through changes and avoiding STL. Instead, I used the MFC container classes and all container classes were available with the framework being used.
I also never used smart pointers. 8)
So I am considering new features in C ++ (as of VS 2013)
The following compiles and works great:
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;
}
You can't:
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)
{
}
The following error message appears:
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> ]
So, I tried the standard iterators:
for (auto thing = things.begin(); thing != things.end(); ++thing)
{
cout << "Name: " << (*thing)->getName() << " age: " << (*thing)->getAge() << endl;
}
which compiles fine, so why doesn't the for (auto thing: things) syntax work?
Here's my definition for 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;
};
and the code:
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)
{
}
I added a default constructor and a copy constructor, but still get the function removed.
source to share
auto thing : things
copies by value, which is disabled for unique_ptr
. Use instead:
auto &thing : things
The difference between this case and an iterator based loop is what is auto thing
defined in this case according to auto thing = *begin;
( see here for more information).
However, when you write auto thing = things.begin();
, thing
in fact, an iterator, so everything is in order.
source to share
In some cases (for example, if things
it turns out vector<bool>
) for (auto& thing : things)
it will not compile. A more general approach is to use
for (auto&& thing : things)
This is the syntax that C ++ 17 will implicitly use for loop-based ( for (thing : things)
) ranges , so you might start getting used to it right now.
source to share
In addition to using
for (auto & thing : things)
to access your objects instead of a copy, consider this:
things.push_back(unique_ptr<Thing>(new Thing("tom", 23)));
This creates a new chunk Thing
on the heap and pushes the vector pointer over it things
. Why not just save Thing
in things
and let the vector handle all the memory for you?
things.push_back(Thing("tom", 23);
source to share