C ++ 11 Immovable Type

Possible duplicate:
Why are C ++ 11 remote functions involved in overload resolution?

I have two questions about the following C ++ 11 code:

#include <iostream> using namespace std; struct A { A() { cout << "Default c-tor" << endl; } A(const A&) { cout << "Copy c-tor" << endl; } A(A&&) = delete; }; A f() { A a; return a; } int main() { A b = f(); return 0; } 

I get the following compilation errors using gcc and clang

gcc-4.7.2 (g ++ --std = C ++ 11 main.cpp):

 main.cpp: In function 'A f()': main.cpp:16:9: error: use of deleted function 'A::A(A&&)' main.cpp:8:2: error: declared here main.cpp: In function 'int main()': main.cpp:21:10: error: use of deleted function 'A::A(A&&)' main.cpp:8:2: error: declared here 

clang-3.0 (clang ++ --std = C ++ 11 main.cpp):

 main.cpp:19:4: error: call to deleted constructor of 'A' A b = f(); ^ ~~~ main.cpp:8:2: note: function has been explicitly marked deleted here A(A&&) = delete; ^ 1 error generated. 
  • Should the compiler use a copy constructor if the move constructor is explicitly deleted?
  • Does anyone know what to use for the "fixed" types?

Thanks in advance.

+11
c ++ gcc c ++ 11 move-semantics clang
Dec 29
source share
4 answers
 A(A&&) = delete; 

Declaring and defining it as delete still declares it and does not make it completely non-existent. Rather, it is similar (but not identical), declaring it empty and private. For example:

 private: A(A&&){} 

Actually, it was a trick that was sometimes used for other statements before = delete was available. Again, it exists in the sense of a search, but its call is never resolved, and in permissions in C ++ (almost or in all cases) execution is called after everything else, for example, permission to overload, name search.

The standard actually says (8.4.3)

The remote function is implicitly built-in.

And noting (what I find), saying that remote functions should not be involved in finding names.

In addition, from 8.4.3

A program that refers to a remote function implicitly or explicitly, except to state it, is poorly formed. [Note: this includes calling the function implicitly or explicitly and forms a pointer or pointer to an element to the function. It is even used for references to expressions that are not potentially evaluated.

+6
Dec 29
source share

This is a bit of an exploratory task, but I think the declaration of the move constructor states that the move constructor should be considered. When it gets delete d, it means that objects can be moved where they can be moved if there is a move constructor. If you need an object that does not move but is copied, you simply declare the copy constructor, and you will not mention the move constructor.

I did not quite find the instruction in the standard, but I explicitly declare it above, but in paragraph 12.8 [class.copy] there is a note containing the following wording:

[Note. If the move constructor is implicitly declared or explicitly specified, expressions that otherwise call the move constructor may instead call the copy constructor. -end note]

+2
Dec 29
source share

When you delete a move constructor, it does not remove it from the set of functions found when searching by name. Whenever your code usually uses a move constructor, you get an error message because, although it was found, it was deleted.

You have two moves in the code. First, when you return a , because when copying is possible, and the object to be copied is denoted by lvalue ( a , here), it is treated as a move. The second is in assigning A b = f() , because a f() gives you a temporary one that is not yet bound to a link.

If you want the copy constructor to be found, and not the remote move constructor, you just have to get rid of your remote definition.

+2
Dec 29 '12 at 20:23
source share

From a working draft C ++ 2012-11-02

8.4.3 Deleted Definitions [dcl.fct.def.delete]
...
2 A program that refers to a remote function implicitly or explicitly, except for declaring it, is poorly formed. [Note: this includes calling the function implicitly or explicitly and forming a pointer or pointer to an element to the function. It is even used for references in expressions that are not potentially evaluated. If a function is overloaded, it is referenced only if the function is selected using overload resolution. - final note]
...
4 The remote function is implicitly built-in.

Because the referring move constructor is referencing, the program is poorly formed.

"Use" for an immovable type can be prevented from moving and thus prevent the return of a local object. I have not seen such a use myself, and I do not know if that makes sense at all, but YMMV.

+1
Dec 29
source share



All Articles