C++11 moves

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

43 Replies - 1068 Views - Last Post: 03 September 2013 - 03:12 PM Rate Topic: -----

#16 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2983
  • Posts: 10,313
  • Joined: 08-August 08

Re: C++11 moves

Posted 01 September 2013 - 06:17 PM

That's odd. Look at line 43:
myvector.push_back(A(i));

size_t i should be long and the constructor is expecting an int. You should get a warning about that. I'm wondering if C++11 and how it's implemented has something to do with both your lack of warning and my failing to compile.
Was This Post Helpful? 0
  • +
  • -

#17 jimblumberg  Icon User is online

  • member icon


Reputation: 4066
  • View blog
  • Posts: 12,548
  • Joined: 25-December 09

Re: C++11 moves

Posted 01 September 2013 - 06:57 PM

No, size_t is not a long. The size_t is an unsigned type, the actual type depends upon the compiler and operating system. Quite often it is an unsigned int, but it will never be a signed integral value.

Jim
Was This Post Helpful? 0
  • +
  • -

#18 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2983
  • Posts: 10,313
  • Joined: 08-August 08

Re: C++11 moves

Posted 01 September 2013 - 08:58 PM

Sorry, you're right. Still, shouldn't an unsigned int generate a loss of precision warning when converting to an int?
Was This Post Helpful? 0
  • +
  • -

#19 jimblumberg  Icon User is online

  • member icon


Reputation: 4066
  • View blog
  • Posts: 12,548
  • Joined: 25-December 09

Re: C++11 moves

Posted 01 September 2013 - 10:23 PM

What code are you talking about, your's from the first post or vividexstance code from post #3?


With your unmodified code from post #1 I get the following warnings:

Quote

||=== c++homework, Debug ===|
main.cpp||In function ‘int main(int, const char**)’:|
main.cpp|49|warning: comparison between signed and unsigned integer expressions [-Wsign-compare]|
main.cpp|39|warning: unused parameter ‘argc’ [-Wunused-parameter]|
main.cpp|39|warning: unused parameter ‘argv’ [-Wunused-parameter]|
||=== Build finished: 0 errors, 3 warnings (0 minutes, 2 seconds) ===|


When compiling the unmodified code from post#3 I get these messages:

Quote

/home/jim/c++homework/main.cpp|40|warning: unused parameter ‘argc’ [-Wunused-parameter]|
/home/jim/c++homework/main.cpp|40|warning: unused parameter ‘argv’ [-Wunused-parameter]|
/opt/gcc-4.8.1/include/c++/4.8.1/bits/stl_algobase.h||In instantiation of ‘static _OI std::__copy_move<true, false, std::random_access_iterator_tag>::__copy_m(_II, _II, _OI) [with _II = A*; _OI = A*]’:|
/opt/gcc-4.8.1/include/c++/4.8.1/bits/stl_algobase.h|390|required from ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = true; _II = A*; _OI = A*]’|
/opt/gcc-4.8.1/include/c++/4.8.1/bits/stl_algobase.h|428|required from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = true; _II = __gnu_cxx::__normal_iterator<A*, std::vector<A> >; _OI = __gnu_cxx::__normal_iterator<A*, std::vector<A> >]’|
/opt/gcc-4.8.1/include/c++/4.8.1/bits/stl_algobase.h|492|required from ‘_OI std::move(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<A*, std::vector<A> >; _OI = __gnu_cxx::__normal_iterator<A*, std::vector<A> >]’|
/opt/gcc-4.8.1/include/c++/4.8.1/bits/vector.tcc|138|required from ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::iterator) [with _Tp = A; _Alloc = std::allocator<A>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<A*, std::vector<A> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = A*]’|
/home/jim/c++homework/main.cpp|55|required from here|
/opt/gcc-4.8.1/include/c++/4.8.1/bits/stl_algobase.h|354|error: use of deleted function ‘A& A::operator=(const A&)’|
/home/jim/c++homework/main.cpp|8|note: ‘A& A::operator=(const A&)’ is implicitly declared as deleted because ‘A’ declares a move constructor or move assignment operator|
||=== Build finished: 1 errors, 8 warnings (0 minutes, 1 seconds) ===|



Jim

This post has been edited by jimblumberg: 01 September 2013 - 10:30 PM

Was This Post Helpful? 0
  • +
  • -

#20 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 659
  • View blog
  • Posts: 2,268
  • Joined: 31-December 10

Re: C++11 moves

Posted 02 September 2013 - 05:12 AM

How are you compiling that jim? The only difference I can see is that you're using 4.8.1 and I'm using 4.6.3.
Was This Post Helpful? 0
  • +
  • -

#21 jimblumberg  Icon User is online

  • member icon


Reputation: 4066
  • View blog
  • Posts: 12,548
  • Joined: 25-December 09

Re: C++11 moves

Posted 02 September 2013 - 06:16 AM

I use g++ version 4.8.1 with the following switches:
-Wshadow
-Winit-self
-Wredundant-decls
-Wcast-align
-Wundef
-Wfloat-equal
-Winline
-Wunreachable-code
-Wmissing-declarations
-Wmissing-include-dirs
-Wswitch-enum
-Wswitch-default
-Wzero-as-null-pointer-constant
-Wmain
-pedantic-errors
-pedantic
-Wextra
-Wall
-ansi
-g
-std=c++11

I get the same error/warning messages when compiling with g++ version 4.7.2, I don't currently have a 4.6.x version to test against.

Jim

This post has been edited by jimblumberg: 02 September 2013 - 06:17 AM

Was This Post Helpful? 0
  • +
  • -

#22 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2983
  • Posts: 10,313
  • Joined: 08-August 08

Re: C++11 moves

Posted 02 September 2013 - 06:21 AM

View Postjimblumberg, on 02 September 2013 - 01:23 AM, said:

What code are you talking about, your's from the first post or vividexstance code from post #3?

Post #3. Interesting that you're getting the same error I am, but your description says the copy constructor is deleted because a move constructor is declared:

View Postjimblumberg, on 02 September 2013 - 01:23 AM, said:

Quote

/opt/gcc-4.8.1/include/c++/4.8.1/bits/stl_algobase.h|354|error: use of deleted function A& A::operator=(const A&)|
/home/jim/c++homework/main.cpp|8|note: A& A::operator=(const A&) is implicitly declared as deleted because A declares a move constructor or move assignment operator|

I'm guessing that's true on my system too. I wonder why a move would cause any method or any attribute to be deleted.
Was This Post Helpful? 0
  • +
  • -

#23 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 659
  • View blog
  • Posts: 2,268
  • Joined: 31-December 10

Re: C++11 moves

Posted 02 September 2013 - 06:31 AM

View Postjimblumberg, on 02 September 2013 - 09:16 AM, said:

I use g++ version 4.8.1 with the following switches:
-Wshadow
-Winit-self
-Wredundant-decls
-Wcast-align
-Wundef
-Wfloat-equal
-Winline
-Wunreachable-code
-Wmissing-declarations
-Wmissing-include-dirs
-Wswitch-enum
-Wswitch-default
-Wzero-as-null-pointer-constant
-Wmain
-pedantic-errors
-pedantic
-Wextra
-Wall
-ansi
-g
-std=c++11

I get the same error/warning messages when compiling with g++ version 4.7.2, I don't currently have a 4.6.x version to test against.

Jim

I have all those command-line options except for -Wzero-as-null-pointer-constant, so here's the command line:

Quote

g++ -Wall -Wextra -Wshadow -Winit-self -Wredundant-decls -Wcast-align -Wundef -Wfloat-equal -Winline -Wunreachable-code -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Wmain -pedantic-errors -pedantic -ansi -g -std=c++0x moveTest.cpp -o moveTest
moveTest.cpp:38:5: warning: unused parameter argc [-Wunused-parameter]
moveTest.cpp:38:5: warning: unused parameter argv [-Wunused-parameter]

For the following code:
#include <iostream>
#include <string>
#include <vector>
#include <utility>

class A
{
public:
	int number;
	
	A(int n) : number(n)
	{
		std::cout << "A: " << number << " " << this << " created." << std::endl;
	}
	
	A(A &&B)/> : number(std::move(b.number))
	{
		std::cout << "A:" << this << " moved from " << &b << std::endl;
	}
	
	A(const A & aIn)
	{
		std::cout << "A:" << this << " copied from " << &aIn << std::endl;
		number = aIn.number;
	}

	~A()
	{
		std::cout << "~A ("<< number << ") " << this << std::endl;
	}
	
	void Am_I_here()
	{
		std::cout << "A ("<< number << ") is here. " << this << std::endl;
	}
};

int main(int argc, const char * argv[])
{
	std::vector <A> myvector;
	for (size_t i = 0; i < 9; i++) {
		std::cout <<"push "<< i << std::endl;
		myvector.push_back(A(i));
		myvector[i].Am_I_here();
	}

	std::cout << "Testing existence of objects:"<< std::endl;
	for (size_t i = 0; i < myvector.size(); i++) {
		myvector[i].Am_I_here();
	}
	std::cout << "erasing"<< std::endl;
	
	myvector.erase(myvector.begin()+1);
	
	std::cout << "Finishing..."<< std::endl;
    return 0;
}

Was This Post Helpful? 0
  • +
  • -

#24 jimblumberg  Icon User is online

  • member icon


Reputation: 4066
  • View blog
  • Posts: 12,548
  • Joined: 25-December 09

Re: C++11 moves

Posted 02 September 2013 - 06:56 AM

After creating the operator= like:

   A& operator=(const A& n)
    {
        number = n.number;
        std::cout << "A: " << number << " " << this << " ASSIGNED." << std::endl;
        return(*this);
    }


I get the following output:

Quote

push 0
A: 0 0xbfce65f4 created.
A:0x9828008 moved from 0xbfce65f4
~A (0) 0xbfce65f4
A (0) is here. 0x9828008
push 1
A: 1 0xbfce65f4 created.
A:0x982801c moved from 0xbfce65f4
A:0x9828018 copied from 0x9828008
~A (0) 0x9828008
~A (1) 0xbfce65f4
A (1) is here. 0x982801c
push 2
A: 2 0xbfce65f4 created.
A:0x9828030 moved from 0xbfce65f4
A:0x9828028 copied from 0x9828018
A:0x982802c copied from 0x982801c
~A (0) 0x9828018
~A (1) 0x982801c
~A (2) 0xbfce65f4
A (2) is here. 0x9828030
push 3
A: 3 0xbfce65f4 created.
A:0x9828034 moved from 0xbfce65f4
~A (3) 0xbfce65f4
A (3) is here. 0x9828034
push 4
A: 4 0xbfce65f4 created.
A:0x9828050 moved from 0xbfce65f4
A:0x9828040 copied from 0x9828028
A:0x9828044 copied from 0x982802c
A:0x9828048 copied from 0x9828030
A:0x982804c copied from 0x9828034
~A (0) 0x9828028
~A (1) 0x982802c
~A (2) 0x9828030
~A (3) 0x9828034
~A (4) 0xbfce65f4
A (4) is here. 0x9828050
push 5
A: 5 0xbfce65f4 created.
A:0x9828054 moved from 0xbfce65f4
~A (5) 0xbfce65f4
A (5) is here. 0x9828054
push 6
A: 6 0xbfce65f4 created.
A:0x9828058 moved from 0xbfce65f4
~A (6) 0xbfce65f4
A (6) is here. 0x9828058
push 7
A: 7 0xbfce65f4 created.
A:0x982805c moved from 0xbfce65f4
~A (7) 0xbfce65f4
A (7) is here. 0x982805c
push 8
A: 8 0xbfce65f4 created.
A:0x9828088 moved from 0xbfce65f4
A:0x9828068 copied from 0x9828040
A:0x982806c copied from 0x9828044
A:0x9828070 copied from 0x9828048
A:0x9828074 copied from 0x982804c
A:0x9828078 copied from 0x9828050
A:0x982807c copied from 0x9828054
A:0x9828080 copied from 0x9828058
A:0x9828084 copied from 0x982805c
~A (0) 0x9828040
~A (1) 0x9828044
~A (2) 0x9828048
~A (3) 0x982804c
~A (4) 0x9828050
~A (5) 0x9828054
~A (6) 0x9828058
~A (7) 0x982805c
~A (8) 0xbfce65f4
A (8) is here. 0x9828088
Testing existence of objects:
A (0) is here. 0x9828068
A (1) is here. 0x982806c
A (2) is here. 0x9828070
A (3) is here. 0x9828074
A (4) is here. 0x9828078
A (5) is here. 0x982807c
A (6) is here. 0x9828080
A (7) is here. 0x9828084
A (8) is here. 0x9828088
erasing
A: 2 0x982806c ASSIGNED.
A: 3 0x9828070 ASSIGNED.
A: 4 0x9828074 ASSIGNED.
A: 5 0x9828078 ASSIGNED.
A: 6 0x982807c ASSIGNED.
A: 7 0x9828080 ASSIGNED.
A: 8 0x9828084 ASSIGNED.
~A (8) 0x9828088
8
Finishing...
~A (0) 0x9828068
~A (2) 0x982806c
~A (3) 0x9828070
~A (4) 0x9828074
~A (5) 0x9828078
~A (6) 0x982807c
~A (7) 0x9828080
~A (8) 0x9828084


Jim
Was This Post Helpful? 1
  • +
  • -

#25 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2983
  • Posts: 10,313
  • Joined: 08-August 08

Re: C++11 moves

Posted 02 September 2013 - 07:11 AM

Hmmm, and with that, I get this:

Quote

push 0
A: 0 0x7fff5fbff8d8 created.
A:0x1001000e0 moved from 0x7fff5fbff8d8
~A (0) 0x7fff5fbff8d8
A (0) is here. 0x1001000e0
push 1
A: 1 0x7fff5fbff8d8 created.
A:0x100103af4 moved from 0x7fff5fbff8d8
A:0x100103af0 copied from 0x1001000e0
~A (0) 0x1001000e0
~A (1) 0x7fff5fbff8d8
A (1) is here. 0x100103af4
push 2
A: 2 0x7fff5fbff8d8 created.
A:0x1001000e8 moved from 0x7fff5fbff8d8
A:0x1001000e4 copied from 0x100103af4
A:0x1001000e0 copied from 0x100103af0
~A (1) 0x100103af4
~A (0) 0x100103af0
~A (2) 0x7fff5fbff8d8
A (2) is here. 0x1001000e8
push 3
A: 3 0x7fff5fbff8d8 created.
A:0x1001000ec moved from 0x7fff5fbff8d8
~A (3) 0x7fff5fbff8d8
A (3) is here. 0x1001000ec
push 4
A: 4 0x7fff5fbff8d8 created.
A:0x100103b10 moved from 0x7fff5fbff8d8
A:0x100103b0c copied from 0x1001000ec
A:0x100103b08 copied from 0x1001000e8
A:0x100103b04 copied from 0x1001000e4
A:0x100103b00 copied from 0x1001000e0
~A (3) 0x1001000ec
~A (2) 0x1001000e8
~A (1) 0x1001000e4
~A (0) 0x1001000e0
~A (4) 0x7fff5fbff8d8
A (4) is here. 0x100103b10
push 5
A: 5 0x7fff5fbff8d8 created.
A:0x100103b14 moved from 0x7fff5fbff8d8
~A (5) 0x7fff5fbff8d8
A (5) is here. 0x100103b14
push 6
A: 6 0x7fff5fbff8d8 created.
A:0x100103b18 moved from 0x7fff5fbff8d8
~A (6) 0x7fff5fbff8d8
A (6) is here. 0x100103b18
push 7
A: 7 0x7fff5fbff8d8 created.
A:0x100103b1c moved from 0x7fff5fbff8d8
~A (7) 0x7fff5fbff8d8
A (7) is here. 0x100103b1c
push 8
A: 8 0x7fff5fbff8d8 created.
A:0x100103b40 moved from 0x7fff5fbff8d8
A:0x100103b3c copied from 0x100103b1c
A:0x100103b38 copied from 0x100103b18
A:0x100103b34 copied from 0x100103b14
A:0x100103b30 copied from 0x100103b10
A:0x100103b2c copied from 0x100103b0c
A:0x100103b28 copied from 0x100103b08
A:0x100103b24 copied from 0x100103b04
A:0x100103b20 copied from 0x100103b00
~A (7) 0x100103b1c
~A (6) 0x100103b18
~A (5) 0x100103b14
~A (4) 0x100103b10
~A (3) 0x100103b0c
~A (2) 0x100103b08
~A (1) 0x100103b04
~A (0) 0x100103b00
~A (8) 0x7fff5fbff8d8
A (8) is here. 0x100103b40
Testing existence of objects:
A (0) is here. 0x100103b20
A (1) is here. 0x100103b24
A (2) is here. 0x100103b28
A (3) is here. 0x100103b2c
A (4) is here. 0x100103b30
A (5) is here. 0x100103b34
A (6) is here. 0x100103b38
A (7) is here. 0x100103b3c
A (8) is here. 0x100103b40
erasing
A: 2 0x100103b24 ASSIGNED.
A: 3 0x100103b28 ASSIGNED.
A: 4 0x100103b2c ASSIGNED.
A: 5 0x100103b30 ASSIGNED.
A: 6 0x100103b34 ASSIGNED.
A: 7 0x100103b38 ASSIGNED.
A: 8 0x100103b3c ASSIGNED.
~A (8) 0x100103b40
Finishing...
~A (8) 0x100103b3c
~A (7) 0x100103b38
~A (6) 0x100103b34
~A (5) 0x100103b30
~A (4) 0x100103b2c
~A (3) 0x100103b28
~A (2) 0x100103b24
~A (0) 0x100103b20

That just confuses me more because I thought the copy method was deleted. I thought I'd see "ASSIGNED" everywhere I see "copied from".
Was This Post Helpful? 0
  • +
  • -

#26 jimblumberg  Icon User is online

  • member icon


Reputation: 4066
  • View blog
  • Posts: 12,548
  • Joined: 25-December 09

Re: C++11 moves

Posted 02 September 2013 - 07:27 AM

No the error message was complaining about the assignment operator:

Quote

/home/jim/c++homework/main.cpp|55|required from here|
/opt/gcc-4.8.1/include/c++/4.8.1/bits/stl_algobase.h|354|error: use of deleted function ‘A& A::operator=(const A&)’|


This seems to be an issue of the Rule of Three. When you defined the copy constructor and destructor you should have defined the copy assignment operator. It looks like this rule also extends to the move operations as well.

Also when I implement the move assignment operator and the assignment operator:
    A& operator=(const A&& n)
    {
        number = std::move(n.number);
        std::cout << "A: " << number << " " << this << " MOVED." << std::endl;
        return(*this);
    }
    A& operator=(const A& n)
    {
        number = n.number;
        std::cout << "A: " << number << " " << this << " COPY ASSIGNED." << std::endl;
        return(*this);
    }


The move version is called instead of the copy.

Quote

...
erasing
A: 2 0x999d06c MOVED.
A: 3 0x999d070 MOVED.
A: 4 0x999d074 MOVED.
A: 5 0x999d078 MOVED.
A: 6 0x999d07c MOVED.
A: 7 0x999d080 MOVED.
A: 8 0x999d084 MOVED.
~A (8) 0x999d088
...


Jim

This post has been edited by jimblumberg: 02 September 2013 - 07:29 AM

Was This Post Helpful? 1
  • +
  • -

#27 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2983
  • Posts: 10,313
  • Joined: 08-August 08

Re: C++11 moves

Posted 02 September 2013 - 08:43 AM

Ok, but why is the copy still being used when the vector needs to expand? Is that something I can control?

Quote

push 0
A: 0 0x7fff5fbff8d8 created.
A:0x1001000e0 moved from 0x7fff5fbff8d8
~A (0) 0x7fff5fbff8d8
A (0) is here. 0x1001000e0
push 1
A: 1 0x7fff5fbff8d8 created.
A:0x100103af4 moved from 0x7fff5fbff8d8
A:0x100103af0 copied from 0x1001000e0
~A (0) 0x1001000e0
~A (1) 0x7fff5fbff8d8
A (1) is here. 0x100103af4
push 2
A: 2 0x7fff5fbff8d8 created.
A:0x1001000e8 moved from 0x7fff5fbff8d8
A:0x1001000e4 copied from 0x100103af4
A:0x1001000e0 copied from 0x100103af0
~A (1) 0x100103af4
~A (0) 0x100103af0
~A (2) 0x7fff5fbff8d8
A (2) is here. 0x1001000e8
push 3
A: 3 0x7fff5fbff8d8 created.
A:0x1001000ec moved from 0x7fff5fbff8d8
~A (3) 0x7fff5fbff8d8
A (3) is here. 0x1001000ec
push 4
A: 4 0x7fff5fbff8d8 created.
A:0x100103b10 moved from 0x7fff5fbff8d8
A:0x100103b0c copied from 0x1001000ec
A:0x100103b08 copied from 0x1001000e8
A:0x100103b04 copied from 0x1001000e4
A:0x100103b00 copied from 0x1001000e0
~A (3) 0x1001000ec
~A (2) 0x1001000e8
~A (1) 0x1001000e4
~A (0) 0x1001000e0
~A (4) 0x7fff5fbff8d8
A (4) is here. 0x100103b10
push 5
A: 5 0x7fff5fbff8d8 created.
A:0x100103b14 moved from 0x7fff5fbff8d8
~A (5) 0x7fff5fbff8d8
A (5) is here. 0x100103b14
push 6
A: 6 0x7fff5fbff8d8 created.
A:0x100103b18 moved from 0x7fff5fbff8d8
~A (6) 0x7fff5fbff8d8
A (6) is here. 0x100103b18
push 7
A: 7 0x7fff5fbff8d8 created.
A:0x100103b1c moved from 0x7fff5fbff8d8
~A (7) 0x7fff5fbff8d8
A (7) is here. 0x100103b1c
push 8
A: 8 0x7fff5fbff8d8 created.
A:0x100103b40 moved from 0x7fff5fbff8d8
A:0x100103b3c copied from 0x100103b1c
A:0x100103b38 copied from 0x100103b18
A:0x100103b34 copied from 0x100103b14
A:0x100103b30 copied from 0x100103b10
A:0x100103b2c copied from 0x100103b0c
A:0x100103b28 copied from 0x100103b08
A:0x100103b24 copied from 0x100103b04
A:0x100103b20 copied from 0x100103b00
~A (7) 0x100103b1c
~A (6) 0x100103b18
~A (5) 0x100103b14
~A (4) 0x100103b10
~A (3) 0x100103b0c
~A (2) 0x100103b08
~A (1) 0x100103b04
~A (0) 0x100103b00
~A (8) 0x7fff5fbff8d8
A (8) is here. 0x100103b40
Testing existence of objects:
A (0) is here. 0x100103b20
A (1) is here. 0x100103b24
A (2) is here. 0x100103b28
A (3) is here. 0x100103b2c
A (4) is here. 0x100103b30
A (5) is here. 0x100103b34
A (6) is here. 0x100103b38
A (7) is here. 0x100103b3c
A (8) is here. 0x100103b40
erasing
A: 2 0x100103b24 MOVED.
A: 3 0x100103b28 MOVED.
A: 4 0x100103b2c MOVED.
A: 5 0x100103b30 MOVED.
A: 6 0x100103b34 MOVED.
A: 7 0x100103b38 MOVED.
A: 8 0x100103b3c MOVED.
~A (8) 0x100103b40
Finishing...
~A (8) 0x100103b3c
~A (7) 0x100103b38
~A (6) 0x100103b34
~A (5) 0x100103b30
~A (4) 0x100103b2c
~A (3) 0x100103b28
~A (2) 0x100103b24
~A (0) 0x100103b20

#include <iostream>
#include <string>
#include <vector>
#include <utility>

class A
{
public:
	int number;
	
	A(int n) : number(n)
	{
		std::cout << "A: " << number << " " << this << " created." << std::endl;
	}
	
	A(A&& b ) : number(std::move(b.number))
	{
		std::cout << "A:" << this << " moved from " << &b << std::endl;
	}
	
	A(const A & aIn)
	{
		std::cout << "A:" << this << " copied from " << &aIn << std::endl;
		number = aIn.number;
	}
	
	~A()
	{
		std::cout << "~A ("<< number << ") " << this << std::endl;
	}
	
	void Am_I_here()
	{
		std::cout << "A ("<< number << ") is here. " << this << std::endl;
	}
	
	A& operator=(const A&& n)
	{
		number = std::move(n.number);
    std::cout << "A: " << number << " " << this << " MOVED." << std::endl;
    return(*this);
	}
	
	A& operator=(const A& n)
	{
		number = n.number;
		std::cout << "A: " << number << " " << this << " COPY ASSIGNED." << std::endl;
		return(*this);
	}
	
};

int main(int argc, const char * argv[])
{
	std::vector <A> myvector;

	for (size_t i = 0; i < 9; i++) {
		std::cout <<"push "<< i << std::endl;
		myvector.push_back(A(i));
		myvector[i].Am_I_here();
	}
	
	std::cout << "Testing existence of objects:"<< std::endl;
	for (size_t i = 0; i < myvector.size(); i++) {
		myvector[i].Am_I_here();
	}
	std::cout << "erasing"<< std::endl;
	
	myvector.erase(myvector.begin()+1);
	
	std::cout << "Finishing..."<< std::endl;
	return 0;
}


Was This Post Helpful? 0
  • +
  • -

#28 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2983
  • Posts: 10,313
  • Joined: 08-August 08

Re: C++11 moves

Posted 02 September 2013 - 08:50 AM

One more thing: the reason I'm interested in this is that I'm assuming a move will be faster than a copy, but I'm not sure that's true in all cases. I've got a specific project in mind for this: an agent based model. Right now I have the beginnings of a model using a vector of pointers, but if move is fast enough I'd use a vector of objects. One of the more important parts for speed would be what happens when I delete an object.
Was This Post Helpful? 0
  • +
  • -

#29 jimblumberg  Icon User is online

  • member icon


Reputation: 4066
  • View blog
  • Posts: 12,548
  • Joined: 25-December 09

Re: C++11 moves

Posted 02 September 2013 - 09:35 AM

Quote

Ok, but why is the copy still being used when the vector needs to expand?


Can you be a little more explicit? I'm not sure I understand the question. What part of your code are you talking about.

Quote

One more thing: the reason I'm interested in this is that I'm assuming a move will be faster than a copy, but I'm not sure that's true in all cases.

If the object just consists of POD types then move versus copy will probably result in very little speed differences. But the only real way of determining which is faster is by careful profiling of the code in question.

Quote

Right now I have the beginnings of a model using a vector of pointers, but if move is fast enough I'd use a vector of objects.


Again the only sure way to tell which is faster is to profile both methods.

Quote

One of the more important parts for speed would be what happens when I delete an object.


Here again the only sure way to tell is to profile both methods. But when deleting an object you still must properly destruct the object to properly free the memory allocated.

If I was writing the program I would start with a vector of objects and only go with the pointers if and when I noticed an actual speed problem. But before I changed anything I would make sure my assumptions about where the problems were occurring were correct by properly profiling the program.

Jim
Was This Post Helpful? 1
  • +
  • -

#30 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2983
  • Posts: 10,313
  • Joined: 08-August 08

Re: C++11 moves

Posted 02 September 2013 - 09:54 AM

Look at the output from post #28. For example:

Quote

push 8
A: 8 0x7fff5fbff8d8 created.
A:0x100103b40 moved from 0x7fff5fbff8d8
A:0x100103b3c copied from 0x100103b1c
A:0x100103b38 copied from 0x100103b18
A:0x100103b34 copied from 0x100103b14
A:0x100103b30 copied from 0x100103b10
A:0x100103b2c copied from 0x100103b0c
A:0x100103b28 copied from 0x100103b08
A:0x100103b24 copied from 0x100103b04
A:0x100103b20 copied from 0x100103b00

I see why is would move after the create, but why not move the existing objects too?

I will need to profile the code, but I'd like to know what is generally faster. I assumed that move would be, but it doesn't seem to be doing a byte by byte copy like I had originally thought, so maybe not.

By the way, an agent based model is used to model a population, with each instance of an object usually representing an individual within that population. Modeling a city, state, or country would require anywhere from tens of thousands to a billion objects. Even small differences in speed could make a big difference in overall performance.
Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3