IDE - Visual Studio Express 2013 for Desktop
C++11
Problem - I have a class which is apparently being copied (using copy constructor). If I declare the copy constructor like this:
MyClass(const MyClass&) = delete;
It complains about a reference to a deleted function. I have gone over my entire code twice now and cannot find where an instance of the class would be copied.
Is there any way to find where the reference comes from?
I have tried defining the copy constructor, with a breakpoint in it, but it is never hit.
Sorry it actually does show where the reference is - in some allocator in the STL. I managed to track it down to a std::vector::emplace_back() call - which must cause a copy. I will investigate this.
I'm such a dumbass - I had a vector of MyClass...
Perhaps you have encountered the following compiler bug:
http://connect.microsoft.com/VisualStudio/feedback/details/889420/issue-with-delete
It says that the IDE (IntelliSense) complains while the compiler does not, which would explain why you have not posted any compiler error message and why you could actually execute a compiled program with breakpoints in the first place.
The bug itself is easy to reproduce:
struct Example
{
Example() {}
Example(Example const &) = delete;
};
Example f()
{
return Example();
}
int main()
{
Example e = f();
}
Compiled with VC 2013 like this:
cl /nologo /EHsc /W4 /Za stackoverflow.cpp
No error, no warning.
Now if you go to http://www.compileonline.com/compile_cpp11_online.php instead and compile the very same code with GCC 4.7.2, there are the expected compiler errors:
main.cpp: In function ‘Example f()’:
main.cpp:9:18: error: use of deleted function ‘Example::Example(const Example&)’
return Example();
^
main.cpp:4:3: error: declared here
Example(Example const &) = delete;
^
main.cpp: In function ‘int main()’:
main.cpp:14:17: error: use of deleted function ‘Example::Example(const Example&)’
Example e = f();
^
main.cpp:4:3: error: declared here
Example(Example const &) = delete;
^
So, you actually have two problems:
Your compiler has a bug. This can only be solved by upgrading to a newer version if/when one is available.
Your code invokes the copy constructor for a class which does not allow copying.
The second problem can be solved by considering the rules for when C++ copies an object "indirectly" -- or requires a copy constructor to be present even if the actual copying is optimised away. Inspect the code again looking for the following cases:
void f(MyClass obj);
.MyClass f();
.throw MyClass();
The first one is easily fixed:
void f(MyClass const &obj);
The others require a more thorough redesign, because returning or throwing directly contradicts the idea of preventing copies.