The Intel C++ Compiler version 16.0.3 fails to compile the following code (The same code compiles fine with ICC 16.0.2):
class TestClass { public: // default constructor, destructor, move constructor, move assignment operator TestClass() noexcept = default; ~TestClass() noexcept = default; TestClass(TestClass&&) noexcept = default; TestClass& operator=(TestClass&&) noexcept = default; // delete copy constructor and copy assignment operator TestClass(const TestClass&) noexcept = delete; TestClass& operator=(const TestClass&) noexcept = delete; TestClass Copy() const noexcept; private: int fTestMember; }; TestClass TestClass::Copy() const noexcept { TestClass copy; copy.fTestMember = fTestMember; // This should be possible by return value optimization - neither copy // constructor nor move constructor should be called! return copy; } int main(int argc, char** argv) { TestClass a; TestClass b = a.Copy(); return 0; }
This is on Linux with GCC 6.1.1 backend, but I have reproduced the same problem with GCC 4.9.3 and GCC 5.3.0. The compiler is invoked as follows:
icpc -std=c++11 -o test test.cc
The error message is:
test.cc(28): error: function "TestClass::TestClass(const TestClass &)" (declared at line 13) cannot be referenced -- it is a deleted function
return copy;
^compilation aborted for test.cc (code 2)
If I explicitly declare the move constructor myself like this:
--- test.cc 2016-05-05 17:15:10.314216763 +0200 +++ test.cc.new 2016-05-05 17:19:32.069354954 +0200 @@ -1,9 +1,12 @@ +#include <algorithm> +#include <iostream> + class TestClass { public: // default constructor, destructor, move constructor, move assignment operator TestClass() noexcept = default; ~TestClass() noexcept = default; - TestClass(TestClass&&) noexcept = default; + TestClass(TestClass&&) noexcept; TestClass& operator=(TestClass&&) noexcept = default; // delete copy constructor and copy assignment operator @@ -16,6 +19,12 @@ int fTestMember; }; +TestClass::TestClass(TestClass&& other) noexcept + : fTestMember(std::move(other.fTestMember)) { + + std::cout << "Move constructor."<< std::endl; +} + TestClass TestClass::Copy() const noexcept { TestClass copy;
Then the code compiles. But when the code is then execute, I don't get a "Move constructor." message on stdout so the move constructor was not called.