Discussion:
The initialization of `a` below: is this an example of a direct or copy-initialization?
(too old to reply)
Belloc
2016-08-26 14:11:33 UTC
Permalink
Consider the snippet below:

#include <iostream>
struct A {

A() { std::cout << "default ctor A" << '\n'; }
A(const A&) { std::cout << "copy A" << '\n'; }
};
struct C {

C() { std::cout << "default ctor C" << '\n'; }
operator A() { std::cout << "C::operator A()" << '\n'; return A(); };
};


int main()
{
C c;
A a(c);
}

Compilers clang and gcc (with the switch -fno-elide-constructors) print the
following in C++14 and C++1z.

default ctor C
C::operator A()
default ctor A
copy A
copy A


According to [dcl.init]/16 <http://eel.is/c++draft/dcl.init#16> the
initialization that occurs in A a(c); is a direct-initialization, but the
code clearly uses the copy constructor to initialize a. Then, I ask: as far
as the algorithm shown in [dcl.init]/17 <http://eel.is/c++draft/dcl.init#17>
is concerned, is this a direct or a copy-initialization?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Christof Meerwald
2016-08-26 14:40:01 UTC
Permalink
On Fri, Aug 26, 2016 at 07:11:33AM -0700, Belloc wrote:
[...]
Post by Belloc
int main()
{
C c;
A a(c);
}
[...]
Post by Belloc
According to [dcl.init]/16 <http://eel.is/c++draft/dcl.init#16> the
initialization that occurs in A a(c); is a direct-initialization, but the
Yes.
Post by Belloc
code clearly uses the copy constructor to initialize a.
The direct initialization rules say that "the applicable constructors
are enumerated, and the best one is chosen through overload
resolution". In this case the copy constructor is chosen (but there is
nothing wrong with that).


Christof
--
http://cmeerw.org sip:cmeerw at cmeerw.org
mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2016-08-26 15:01:57 UTC
Permalink
Post by Christof Meerwald
The direct initialization rules say that "the applicable constructors
are enumerated, and the best one is chosen through overload
resolution". In this case the copy constructor is chosen (but there is
nothing wrong with that).
Are you referring to bullet point (17.6.2) or (17.6.3) in N4606?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Christof Meerwald
2016-08-26 15:07:36 UTC
Permalink
Post by Belloc
Post by Christof Meerwald
The direct initialization rules say that "the applicable constructors
are enumerated, and the best one is chosen through overload
resolution". In this case the copy constructor is chosen (but there is
nothing wrong with that).
Are you referring to bullet point (17.6.2) or (17.6.3) in N4606?
Direct initialization is handled by bullet 17.6.2.


Christof
--
http://cmeerw.org sip:cmeerw at cmeerw.org
mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2016-08-26 17:29:37 UTC
Permalink
Post by Christof Meerwald
Direct initialization is handled by bullet 17.6.2.
Not in this case, for 2 reasons:


1. I believe the statement in (7.6.2) "where the cv-unqualified version
of the source type is the same class as, or a derived class of, the class
of the destination" also applies to direct-initialization.
2. But even if this were not the case, (7.6.2) is about converting
constructors and the example calls for a conversion function.

So, as far as I can tell, the algorithm lands in (7.6.3). And that's where
the problem lies, as the phrase "i.e., for the remaining
copy-initialization cases" excludes direct-initialization.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Christof Meerwald
2016-08-26 21:01:18 UTC
Permalink
Post by Belloc
Post by Christof Meerwald
Direct initialization is handled by bullet 17.6.2.
No, it is.
Post by Belloc
1. I believe the statement in (7.6.2) "where the cv-unqualified version
of the source type is the same class as, or a derived class of, the class
of the destination" also applies to direct-initialization.
The text is "if the initialization is direct-initialization, or if it
is copy-initialization where [...]" which makes it pretty clear that
the "where" only applies to "copy-initialization" as it is separated
via ", or if it is".
Post by Belloc
2. But even if this were not the case, (7.6.2) is about converting
constructors and the example calls for a conversion function.
It doesn't say anything about converting constructors in that bullet.
In fact, if you look at 13.3.1.3 it says "For direct-initialization or
default-initialization that is not in the context of
copy-initialization, the candidate functions are all the constructors
of the class of the object being initialized."

As I said, you perform overload resolution on that candidate set and
are left with the copy constructor as it's the only viable function.
Post by Belloc
So, as far as I can tell, the algorithm lands in (7.6.3).
No, it doesn't.
Post by Belloc
And that's where
the problem lies, as the phrase "i.e., for the remaining
copy-initialization cases" excludes direct-initialization.
There is no problem, because that case is handled in the previous
sub-bullet.


Christof
--
http://cmeerw.org sip:cmeerw at cmeerw.org
mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2016-08-27 17:37:39 UTC
Permalink
That's all clear now. Thanks to both, Christof and Johannes.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
'Johannes Schaub' via ISO C++ Standard - Discussion
2016-08-27 11:09:59 UTC
Permalink
Post by Belloc
#include <iostream>
struct A {
A() { std::cout << "default ctor A" << '\n'; }
A(const A&) { std::cout << "copy A" << '\n'; }
};
struct C {
C() { std::cout << "default ctor C" << '\n'; }
operator A() { std::cout << "C::operator A()" << '\n'; return A(); };
};
int main()
{
C c;
A a(c);
}
Compilers clang and gcc (with the switch -fno-elide-constructors) print the
following in C++14 and C++1z.
default ctor C
C::operator A()
default ctor A
copy A
copy A
According to [dcl.init]/16 the initialization that occurs in A a(c); is a
direct-initialization, but the code clearly uses the copy constructor to
initialize a. Then, I ask: as far as the algorithm shown in [dcl.init]/17 is
concerned, is this a direct or a copy-initialization?
So what is wrong with using the copy constructor? It's just a normal
constructor in this context, nothing special. "Direct initialization"
doesn't mean "does not invoke the copy constructor". If it meant that,
how could "A a2(a)" create a copy?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Continue reading on narkive:
Loading...