Move Constructor choosen instead of Copy. [reference to std] - c++

Can anybody enlighten me where I can find
prvalue:
When used as a function argument and when two overloads of the function are available, one taking rvalue reference parameter and the other taking lvalue reference to const parameter, an rvalue binds to the rvalue reference overload (thus, if both copy and move constructors are available, an rvalue argument invokes the move constructor, and likewise with copy and move assignment operators).
from cppreference
in the standard here

In the final working draft (n4659) of the C++17 standard, it is found in 16.3.3 Best viable function [over.match.best] and specifically in the following subsection:
16.3.3.2 Ranking implicit conversion sequences [over.ics.rank]
3 Two implicit conversion sequences of the same form are
indistinguishable conversion sequences unless one of the following
rules applies:
(3.2) — Standard conversion sequence S1 is a better conversion
sequence than standard conversion sequence S2 if
(3.2.1) — S1 is a
proper subsequence of S2 (comparing the conversion sequences in the
canonical form defined by 16.3.3.1.1, excluding any Lvalue
Transformation; the identity conversion sequence is considered to be a
subsequence of any non-identity conversion sequence) or, if not that,
(3.2.2) — the rank of S1 is better than the rank of S2, or S1 and S2
have the same rank and are distinguishable by the rules in the
paragraph below, or, if not that,
(3.2.3) — S1 and S2 are reference
bindings (11.6.3) and neither refers to an implicit object parameter
of a non-static member function declared without a ref-qualifier, and
S1 binds an rvalue reference to an rvalue and S2 binds an lvalue
reference
I believe (3.2.3) applies to your case.
There are some relevant examples that follow:
int i;
int f1();
int&& f2();
int g(const int&);
int g(const int&&);
int j = g(i); // calls g(const int&)
int k = g(f1()); // calls g(const int&&)
int l = g(f2()); // calls g(const int&&)

Related

Array-to-pointer conversion + rvalue-ref: Overload resolution difference GCC vs clang

#include <iostream>
#define FUNC() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
void foo(char const*&& ) FUNC() // A
void foo(char const(&)[4]) FUNC() // B
int main()
{
foo("bar");
}
Demo
When using an rvalue reference in the parameter type of the first overload (A), clang current master unambiguously chooses that overload A over B. GCC current master on the other hand complains about an ambiguity.
I'm quite surprised that the string literal, being an lvalue of 4 char const ([expr.prim.literal]/1, [lex.string]/6) should prefer the array-to-pointer conversion on overload A over the identity conversion on overload B.
Without the rvalue reference, that is void foo(char const*), both GCC and clang reject the call as ambiguous. That's also something I don't fully understand, since I would have guessed that there's still an array-to-pointer conversion and therefore [over.ics.rank]p3.2.1 applies:
Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if
(3.2.1) S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by [over.ics.scs], excluding
any Lvalue Transformation; the identity conversion sequence is
considered to be a subsequence of any non-identity conversion
sequence) or, if not that,
What is going on in either case?
(This is only a partial answer, covering the second case)
What is going on in either case?
Regarding the second case, as to why the following overloads
void foo(char const* ) FUNC() // A
void foo(char const(&)[4]) FUNC() // B
yields ambiguous overloads (for both Clang and GCC); [over.ics.rank]/3.2.1 may seem to favour B, being an identity conversion, over A, requiring an array-to-pointer conversion which in turn is in the conversion category of Lvalue Transformation:
Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if
(3.2.1) S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by [over.ics.scs], excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence) or, if not that,
[...]
However, as I interpret the first emphasized segment above, Lvalue Transformation:s are excluded from both sequences S1 and S2 when applying [over.ics.rank]/3.2.1, and the second emphasized segment applies only after this exclusion has been applied.
As pointed out in a comment by #LanguageLawyer, that the rules indeed allow this ambiguity was highlighted in CWG 1789 which, afaict, have seen no progress or feedback since 2013.
1789. Array reference vs array decay in overload resolution
Section: 12.4.4.3 [over.ics.rank]
Status: drafting
Submitter: Faisal Vali
Date: 2013-10-01
The current rules make an example like
template<class T, size_t N> void foo(T (&)[N]);
template<class T> void foo(T *t);
int arr[3]{1, 2, 3};
foo(arr);
ambiguous, even though the first is an identity match and the second
requires an lvalue transformation. Is this desirable?

Overload resolution between const lvalue reference and rvalue reference

#include <iostream>
#include <string>
void fnc (const std::string&)
{
std::cout<<1;
}
void fnc (std::string&&)
{
std::cout<<2;
}
int main()
{
fnc ("abc");
}
All the compilers choose std::string&& version of fnc, and it is logical, because the temporary std::string is created for a reference binding, but I can't find, where is it described in C++ 14 Standard.
I found one paragraph in there (3.2):
— Standard conversion sequence S1 is a better conversion sequence than
standard conversion sequence S2 if
[...]
— S1 and S2 are reference bindings (8.5.3) and neither refers to an
implicit object parameter of a non-static member function declared
without a ref-qualifier, and S1 binds an rvalue reference to an rvalue
and S2 binds an lvalue reference
But it isn't that case, because S1 binds an rvalue reference to an lvalue ("abc", lvalue of const char[4]).
Where can I find description, by which the second overload is selected?
P.S. I pointed to C++14 Standard instead of C++11, because I know, that there was some defect reports in C++11, linked with rvalue reference binding.
First the compiler performs an implicit array-to-pointer conversion for "abc", so the type of "abc" becomes const char*. Second (and you probably missed that), const char* is converted to a rvalue std::string via the const char* non-explicit constructor of std::string (# 5 in the link). The constructed std::string rvalue is a perfect match for the second overload, so the second overload is chosen.
But it isn't that case, because S1 binds an rvalue reference to an lvalue ("abc", lvalue of const char[4]).
Note that "abc" is a const char[4], not a std::string. But both fnc() take std::string as parameter, and references can't be bound to objects with different type directly. Therefore firstly "abc" needs to be implicitly converted to std::string, which is a temporary, i.e. an rvalue. Then as the stardard says, the rvalue reference overload will be selected.
"abc" cannot be passed directly into either overload of fnc(). For both of them it must be converted to an (rvalue) std::string. But then the cited rule from the standard unequivocally selects fnc(std::string&&) over fnc(const std::string&).

Distinguishing between user-defined conversion sequences by the initial standard conversion sequence

The standard appears to provide two rules for distinguishing between implicit conversion sequences that involve user-defined conversion operators:
c++11
13.3.3 Best viable function [over.match.best]
[...] a viable function F1 is defined to be a better function than another viable function
F2 if [...]
the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the
standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the
entity being initialized) is a better conversion sequence than the standard conversion sequence from
the return type of F2 to the destination type.
13.3.3.2 Ranking implicit conversion sequences [over.ics.rank]
3 - Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of
the following rules applies: [...]
User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion function or constructor or aggregate
initialization and the second standard conversion sequence of U1 is better than the second standard
conversion sequence of U2.
As I understand it, 13.3.3 allows the compiler to distinguish between different user-defined conversion operators, while 13.3.3.2 allows the compiler to distinguish between different functions (overloads of some function f) that each require a user-defined conversion in their arguments (see my sidebar to Given the following code (in GCC 4.3) , why is the conversion to reference called twice?).
Are there any other rules that can distinguish between user-defined conversion sequences? The answer at https://stackoverflow.com/a/1384044/567292 indicates that 13.3.3.2:3 can distinguish between user-defined conversion sequences based on the cv-qualification of the implicit object parameter (to a conversion operator) or of the single non-default parameter to a constructor or aggregate initialisation, but I don't see how that can be relevant given that that would require comparison between the first standard conversion sequences of the respective user-defined conversion sequences, which the standard doesn't appear to mention.
Supposing that S1 is better than S2, where S1 is the first standard conversion sequence of U1 and S2 is the first standard conversion sequence of U2, does it follow that U1 is better than U2? In other words, is this code well-formed?
struct A {
operator int();
operator char() const;
} a;
void foo(double);
int main() {
foo(a);
}
g++ (4.5.1), Clang (3.0) and Comeau (4.3.10.1) accept it, preferring the non-const-qualified A::operator int(), but I'd expect it to be rejected as ambiguous and thus ill-formed. Is this a deficiency in the standard or in my understanding of it?
The trick here is that converting from a class type to a non-class type doesn't actually rank any user-defined conversions as implicit conversion sequences.
struct A {
operator int();
operator char() const;
} a;
void foo(double);
int main() {
foo(a);
}
In the expression foo(a), foo obviously names a non-overloaded non-member function. The call requires copy-initializing (8.5p14) the function parameter, of type double, using the single expression a, which is an lvalue of class type A.
Since the destination type double is not a cv-qualified class type but the source type A is, the candidate functions are defined by section 13.3.1.5, with S=A and T=double. Only conversion functions in class A and any base classes of A are considered. A conversion function is in the set of candidates if:
It is not hidden in class A, and
It is not explicit (since the context is copy-initialization), and
A standard conversion sequence can convert the function's return type (not including any reference qualifiers) to the destination type double.
Okay, both conversion functions qualify, so the candidate functions are
A::operator int(); // F1
A::operator char() const; // F2
Using the rules from 13.3.1p4, each function has the implicit object parameter as the only thing in its parameter list. F1's parameter list is "(lvalue reference to A)" and F2's parameter list is "(lvalue reference to const A)".
Next we check that the functions are viable (13.3.2). Each function has one type in its parameter list, and there is one argument. Is there an implicit conversion sequence for each argument/parameter pair? Sure:
ICS1(F1): Bind the implicit object parameter (type lvalue reference to A) to expression a (lvalue of type A).
ICS1(F2): Bind the implicit object parameter (type lvalue reference to const A) to expression a (lvalue of type A).
Since there's no derived-to-base conversion going on, these reference bindings are considered special cases of the identity conversion (13.3.3.1.4p1). Yup, both functions are viable.
Now we have to determine if one implicit conversion sequence is better than the other. This falls under the fifth sub-item in the big list in 13.3.3.2p3: both are reference bindings to the same type except for top-level cv-qualifiers. Since the referenced type for ICS1(F2) is more cv-qualified than the referenced type for ICS1(F1), ICS1(F1) is better than ICS1(F2).
Therefore F1, or A::operator int(), is the most viable function. And no user-defined conversions (with the strict definition of a type of ICS composed of SCS + (converting constructor or conversion function) + SCS) were even to be compared.
Now if foo were overloaded, user-defined conversions on the argument a would need to be compared. So then the user-defined conversion (identity + A::operator int() + int to double) would be compared to other implicit conversion sequences.

Overload resolution and arrays: which function should be called?

Consider the following program:
#include <cstddef>
#include <cstdio>
void f(char const*&&) { std::puts("char const*&&"); } // (1)
void f(char const* const&) { std::puts("char const* const&"); } // (2)
template <std::size_t N>
void f(char const (&)[N]) { std::puts("char const(&)[N]"); } // (3)
int main()
{
const char data[] = "a";
f(data);
}
Which f should be called? Why?
The latest released versions of three compilers disagree on the answer to this question:
(1) is called when the program is compiled using g++ 4.5.2
(2) is called when the program is compiled using Visual C++ 2010 SP1
(3) is called when the program is compiled using Clang 3.0 (trunk 127530)
Have the overload resolution rules changed substantially in different C++0x drafts? Or, are two of these compilers really just completely wrong? Which overload is the correct overload to be selected per the latest C++0x draft?
First, the conversion sequence of all three is the same, except that for the first two, there is an lvalue transformation (lvalue to rvalue conversion), which however is not used in ordering conversion sequences. All three are exact matches (the function template specialization has parameter type char const(&)[2]).
If you iterate over the rules at 13.3.3.2p3, you stop at this paragraph
S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference.
A conversion sequence cannot be formed if it requires binding an rvalue reference to an lvalue, the spec says at 13.3.3.1.4p3. If you look at how reference binding works at 8.5.3p5 last bullet, it will create a temporary (I think they meant rvalue temporary) of type char const* from the array lvalue and bind the reference to that temporary. Therefor, I think (1) is better than (2). Same holds for (1) against (3), although we wouldn't need this because (3) is a template so in a tie, we would choose (1) again.
In n3225, they changed the reference binding rules so that rvalue references can bind to initializer expressions that are lvalues, as long as the reference will be bound to an rvalue (possibly created by converting the initializer properly before). This could influence the handling by Visual C++, which may not be up to date here.
I'm not sure about clang. Even if it would ignore (1), then it would end up in a tie between (2) and (3), and would need to choose (2) because it's a non-template.
I think that 8.5.3p5 last bullet is confusing because it says "Otherwise a temporary of type ..". It's not clear whether the temporary is regarded as an lvalue or as an rvalue by 13.3.3.1.4p3, which means I'm not sure how the following should really behave according to the exact words of the spec
void f(int &);
void f(int &&);
int main() {
int n = 0;
f(n);
}
If we assume the temporary is treated as an rvalue by clause 13, then we bind an rvalue ref to an rvalue in the second function and an lvalue in the first. Therefor, we will choose the second function and then get a diagnostic by 8.5.3p5 last bullet because T1 and T2 are reference-related. If we assume the temporary is treated as an lvalue by clause 13, then the following would not work
void f(int &&);
int main() {
f(0);
}
Because we would bind an rvalue ref to an lvalue which by clause 13 will make the function non-viable. And if we interpret "binding an rvalue ref to an lvalue" to refer to the initializer expression instead of the final expression bound to, we won't accept the following
void f(float &&);
int main() {
int n = 0;
f(n);
}
This however is valid as of n3225. So there seems to be some confusion - I sent a DR to the committee about this.
I claim that #3 is the function chosen by a conforming compiler.
(1) is better than (2) because "Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference."
(3) is better than both (1) and (2) because it is an identity conversion (the others are exact match conversions) and "Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by 13.3.3.1.1, excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence)"
Template vs non-template is only considered when neither conversion is better "or, if not that..."
oddly enough though, Comeau prefers (2) over (3). This test case fails to compile:
#include <cstddef>
#include <cstdio>
// (1) removed because Comeau doesn't support rvalue-references yet
char f(char const* const&) { std::puts("char const* const&"); return 0; } // (2)
template <std::size_t N>
int f(char const (&)[N]) { std::puts("char const(&)[N]"); return 0; } // (3)
int main()
{
const char data[] = "a";
switch (0) {
case sizeof(char):
break;
case sizeof(f(data)):
break;
}
}
This is a community wiki answer for collecting snippets from the standard (draft 3225).
section 13.3.3 "Best viable function" [over.match.best]
Define ICSi(F) as follows:
if F is a static member function, ICS1(F) is defined such that ICS1(F) is neither better nor worse than
ICS1(G) for any function G, and, symmetrically, ICS1(G) is neither better nor worse than ICS1(F); otherwise,
let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the
type of the i-th parameter of viable function F. 13.3.3.1 defines the implicit conversion sequences and
13.3.3.2 defines what it means for one implicit conversion sequence to be a better conversion sequence or worse conversion sequence than another.
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2)
or, if not that,
the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type
or, if not that,
F1 is a non-template function and F2 is a function template specialization
or, if not that,
F1 and F2 are function template specializations, and the function template for F1 is more specialized
than the template for F2 according to the partial ordering rules described in 14.5.6.2.
If there is exactly one viable function that is a better function than all other viable functions, then it is the one selected by overload resolution; otherwise the call is ill-formed.
section 13.3.3.1.4 "Reference binding" [over.ics.ref]
When a parameter of reference type binds directly (8.5.3) to an argument expression, the implicit conversion
sequence is the identity conversion, unless the argument expression has a type that is a derived class of the
parameter type, in which case the implicit conversion sequence is a derived-to-base conversion (13.3.3.1). If the parameter binds directly to the result of applying a conversion function to the
argument expression, the implicit conversion sequence is a user-defined conversion sequence (13.3.3.1.2), with the second standard conversion sequence either an identity conversion or, if the conversion function
returns an entity of a type that is a derived class of the parameter type, a derived-to-base Conversion.
When a parameter of reference type is not bound directly to an argument expression, the conversion sequence
is the one required to convert the argument expression to the underlying type of the reference according
to 13.3.3.1. Conceptually, this conversion sequence corresponds to copy-initializing a temporary of the
underlying type with the argument expression. Any difference in top-level cv-qualification is subsumed by
the initialization itself and does not constitute a conversion.
section 13.3.3.2 "Ranking implicit conversion sequences" [over.ics.rank]
13.3.3.2 defines a partial ordering of implicit conversion sequences based on the relationships better conversion
sequence and better conversion. If an implicit conversion sequence S1 is defined by these rules to be a better
conversion sequence than S2, then it is also the case that S2 is a worse conversion sequence than S1. If
conversion sequence S1 is neither better than nor worse than conversion sequence S2, S1 and S2 are said to
be indistinguishable conversion sequences.
When comparing the basic forms of implicit conversion sequences (as defined in 13.3.3.1)
a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence, and
a user-defined conversion sequence (13.3.3.1.2) is a better conversion sequence than an ellipsis conversion sequence (13.3.3.1.3).
Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of
the following rules applies:
Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if
S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by 13.3.3.1.1, excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence)
or, if not that,
the rank of S1 is better than the rank of S2, or S1 and S2 have the same rank and are distinguishable by the rules in the paragraph below
or, if not that,
S1 and S2 differ only in their qualification conversion and yield similar types T1 and T2 (4.4), respectively, and the cv-qualification signature of type T1 is a proper subset of the cv-qualification signature of type T2.
or, if not that,
S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of a
non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to
an rvalue and S2 binds an lvalue reference.

non-class rvalues always have cv-unqualified types

§3.10 section 9 says "non-class rvalues always have cv-unqualified types". That made me wonder...
int foo()
{
return 5;
}
const int bar()
{
return 5;
}
void pass_int(int&& i)
{
std::cout << "rvalue\n";
}
void pass_int(const int&& i)
{
std::cout << "const rvalue\n";
}
int main()
{
pass_int(foo()); // prints "rvalue"
pass_int(bar()); // prints "const rvalue"
}
According to the standard, there is no such thing as a const rvalue for non-class types, yet bar() prefers to bind to const int&&. Is this a compiler bug?
EDIT: Apparently, this is also a const rvalue :)
EDIT: This issue seems to be fixed in g++ 4.5.0, both lines print "rvalue" now.
The committee already seems to be aware that there's a problem in this part of the standard. CWG issue 690 talks about a somewhat similar problem with exactly the same part of the standard (in the "additional note" from September, 2009). I'd guess new language will be drafted for that part of the standard soon.
Edit: I've just submitted a post on comp.std.c++, noting the problem and suggesting new wording for the relevant piece of the standard. Unfortunately, being a moderated newsgroup, nearly everybody will probably have forgotten this question by the time it makes it through the approval queue there.
Good point. I guess there are two things to look at: 1) as you pointed out the non-class rvalue thingsy and 2) how overload resolution works:
The selection criteria for the best
function are the number of arguments,
how well the arguments match the
parameter-type-list of the candidate
function, [...]
I haven't seen anything in the standard that tells me non-class rvalues are treated specially during overload resolution.
Your question is covered in the draft of the standard I have though (N-4411) somewhat:
What does come into play is however a parallel reading of reference binding, implicit conversion sequences, references, and overload resolution in general:
13.3.3.1.4 Reference binding
2 When a parameter of reference type
is not bound directly to an argument
expression, the conversion sequence
is the one required to convert the argument expression to the underlying
type of the reference according
to 13.3.3.1.
and
13.3.3.2 Ranking implicit conversion sequences
3 Two implicit conversion sequences of
the same form are indistinguishable
conversion sequences unless one of the
following rules applies:
— Standard conversion sequence S1 is a better conversion sequence than
standard
conversion sequence S2 if
— S1 and S2 are reference bindings (8.5.3) and neither refers to an
implicit object parameter of a
nonstatic
member function declared without a ref-qualifier, and either S1 binds an
lvalue reference
to an lvalue and S2 binds an rvalue reference or S1 binds an rvalue
reference to an rvalue and S2
binds an lvalue reference.
[ Example:
int i;
int f();
int g(const int&);
int g(const int&&);
int j = g(i); // calls g(const int&)
int k = g(f()); // calls g(const int&&)