Question regarding copy constructor

Discussion in 'C++' started by somenath, Oct 21, 2013.

  1. somenath

    somenath Guest

    I have one question regarding the output of the following program.

    #include<iostream>
    using namespace std;

    class A {
    public:
    A(int x) {
    cout<<"Inside constructor A "<<endl;

    }
    A(const A&a) {
    cout<<"Inside copy constructor";
    }
    void operator =( int x) {
    cout<<"Inside assignment operator overloading "<<endl;
    }
    };
    int main(void)
    {
    A a(2);
    A a1 = 2;
    A a2 = a;
    return 0;
    }
    Output
    +++++++++
    Inside constructor A
    Inside constructor A
    Inside copy constructor

    For this code
    A a1 = 2;
    I was expecting the copy constructor would be called. Because my understanding is compiler will create a temporary object using 2 and then that temporary object will be copied to a1 object. Something as follows.
    __tempObj(2);
    A a1 = __tempObj;
    But that is not happening here . The copy constructor is not getting called. Where am I going wrong?
    How the compiler then assigning 2 to object a1?
     
    somenath, Oct 21, 2013
    #1
    1. Advertising

  2. On 21.10.2013 06:15, somenath wrote:
    > The copy constructor is not getting called. Where am I going wrong?


    No matter what a copy constructor does, the compiler is allowed to
    assume, for purposes of optimization, that it does nothing but copying
    the object, and that it does that perfectly.

    The copy constructor is the only such special case, where the compiler
    can just disregard the actual code and assume a perfect implementation.

    Thus, when you have a declaration like

    A a = 2;

    then the formal meaning is

    A a( A( 2 ) );

    that is, a copy construction.

    But while that means that the copy constructor must be ACCESSIBLE, the
    compiler is allowed to optimize this to

    A a( 2 );

    that is, a direct initialization, even if that fails to produce some
    intended side effect in the copy constructor.

    You can find the formal rules for such COPY ELISION in C++11 §12.8/31.


    Cheersw & hth.,

    - Alf
     
    Alf P. Steinbach, Oct 21, 2013
    #2
    1. Advertising

  3. somenath

    K. Frank Guest

    Hi Alf!

    On Monday, October 21, 2013 12:37:04 AM UTC-4, Alf P. Steinbach wrote:
    > On 21.10.2013 06:15, somenath wrote:
    >
    > > The copy constructor is not getting called. Where am I going wrong?

    > ...
    > Thus, when you have a declaration like
    >
    > A a = 2;
    >
    > then the formal meaning is
    >
    > A a( A( 2 ) );
    >
    > that is, a copy construction.
    >
    > But while that means that the copy constructor must be ACCESSIBLE, the
    > compiler is allowed to optimize this to
    >
    > A a( 2 );
    >
    > that is, a direct initialization, even if that fails to produce some
    > intended side effect in the copy constructor.


    I agree that this is the case, but I've often
    wondered why.

    Given that in somenath's example, the constructor
    A(int) exists, and given that the compiler is
    allowed to copy-elide the copy constructor away,
    why does the standard _not_ define

    A a = 2;

    and

    A a(2);

    to be synonymous? That is, why not just define
    A a = 2 to be direct initialization, and be done
    with it?

    Given that the programmer cannot rely on the copy
    constructor getting called in this situation, I
    don't see any reason why letting the compiler
    first construct and then copy construct would be
    advantage. Wouldn't it be simpler and better (and
    fully backward compatible) just to require A a = 2
    to be direct initialization?

    Just wondering ...

    > ...
    > Cheersw & hth.,
    >
    > - Alf



    Thanks.


    K. Frank
     
    K. Frank, Oct 21, 2013
    #3
  4. "K. Frank" <> wrote:
    [...]
    > Given that in somenath's example, the constructor
    > A(int) exists, and given that the compiler is
    > allowed to copy-elide the copy constructor away,
    > why does the standard _not_ define
    >
    > A a = 2;
    >
    > and
    >
    > A a(2);
    >
    > to be synonymous? That is, why not just define
    > A a = 2 to be direct initialization, and be done
    > with it?
    >
    > Given that the programmer cannot rely on the copy
    > constructor getting called in this situation, I
    > don't see any reason why letting the compiler
    > first construct and then copy construct would be
    > advantage. Wouldn't it be simpler and better (and
    > fully backward compatible) just to require A a = 2
    > to be direct initialization?


    Even more so as it is already a special case. Regarding only the syntax,
    you would expect the appropriate assignment operator to be called.

    Tobi
     
    Tobias Müller, Oct 21, 2013
    #4
  5. somenath

    Öö Tiib Guest

    On Monday, 21 October 2013 18:55:47 UTC+3, Tobias Müller wrote:
    > "K. Frank" <> wrote:
    >
    > [...]
    >
    > > Given that in somenath's example, the constructor
    > > A(int) exists, and given that the compiler is
    > > allowed to copy-elide the copy constructor away,
    > > why does the standard _not_ define
    > >
    > > A a = 2;
    > >
    > > and
    > >
    > > A a(2);
    > >
    > > to be synonymous? That is, why not just define
    > > A a = 2 to be direct initialization, and be done
    > > with it?
    > >
    > > Given that the programmer cannot rely on the copy
    > > constructor getting called in this situation, I
    > > don't see any reason why letting the compiler
    > > first construct and then copy construct would be
    > > advantage. Wouldn't it be simpler and better (and
    > > fully backward compatible) just to require A a = 2
    > > to be direct initialization?

    >
    > Even more so as it is already a special case. Regarding only the syntax,
    > you would expect the appropriate assignment operator to be called.


    There certainly won't be assignment operators used in initialization. Most
    coding standards suggest to write what you actually want 'A a(2);' and
    to avoid writing "likely synonymous after optimizations" variants.
     
    Öö Tiib, Oct 21, 2013
    #5
  6. Öö Tiib <> wrote:
    > On Monday, 21 October 2013 18:55:47 UTC+3, Tobias Müller wrote:
    >> "K. Frank" <> wrote:
    >>
    >> [...]
    >>
    >>> Given that in somenath's example, the constructor
    >>> A(int) exists, and given that the compiler is
    >>> allowed to copy-elide the copy constructor away,
    >>> why does the standard _not_ define
    >>>
    >>> A a = 2;
    >>>
    >>> and
    >>>
    >>> A a(2);
    >>>
    >>> to be synonymous? That is, why not just define
    >>> A a = 2 to be direct initialization, and be done
    >>> with it?
    >>>
    >>> Given that the programmer cannot rely on the copy
    >>> constructor getting called in this situation, I
    >>> don't see any reason why letting the compiler
    >>> first construct and then copy construct would be
    >>> advantage. Wouldn't it be simpler and better (and
    >>> fully backward compatible) just to require A a = 2
    >>> to be direct initialization?

    >>
    >> Even more so as it is already a special case. Regarding only the syntax,
    >> you would expect the appropriate assignment operator to be called.

    >
    > There certainly won't be assignment operators used in initialization.


    Yes, that's what I wanted to say. Syntactically it's an assignment, but in
    the context of a declaration it is special cased to actually mean
    initialization. But then, why in a such convoluted way?

    > Most coding standards suggest to write what you actually want 'A a(2);' and
    > to avoid writing "likely synonymous after optimizations" variants.


    The above proposal would provide exactly that. Without relying on
    optimizations.
    But I agree, just writing the appropriate constructor is even better.

    Tobi
     
    Tobias Müller, Oct 21, 2013
    #6
  7. On 10/21/2013 2:42 PM, Tobias Müller wrote:
    > [..] Syntactically it's an assignment, but in
    > the context of a declaration it is special cased to actually mean
    > initialization. But then, why in a such convoluted way?


    <shrug> Why not? This is one of C legacies. It's very likely that in a
    function scope it literally meant the same machine code... And many an
    older folk got used to seeing this form and keep using it. Imagine (a)
    requiring to rewrite millions of lines(*) of

    int a = 42;

    to

    int a { 42 };

    and (b) force scores of thousands of C++ programmers to re-learn to use
    that form from some point on... I don't think it's feasible.

    >> [..]


    *) I don't really know how many lines of such code exist and need to be
    maintained, so might be off by a billion or two.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 21, 2013
    #7
  8. somenath

    James Kanze Guest

    On Monday, 21 October 2013 19:42:58 UTC+1, Tobias Müller wrote:
    > >> Even more so as it is already a special case. Regarding only the syntax,
    > >> you would expect the appropriate assignment operator to be called.


    > > There certainly won't be assignment operators used in initialization.


    > Yes, that's what I wanted to say. Syntactically it's an assignment, but in
    > the context of a declaration it is special cased to actually mean
    > initialization.


    Syntactically, it isn't an assignment. And assignment can only
    occur as part of an expression, and the = sign there is *not*
    part of any expression.

    There are several character sequences that can be both operators
    and punctuation, depending on context: the comma is the most
    noted, but a single colon is also ambiguous in this regard.
    That's obviously not an ideal situation, but it's one we have to
    live with for historical reasons.

    > But then, why in a such convoluted way?


    > > Most coding standards suggest to write what you actually
    > > want 'A a(2);' and to avoid writing "likely synonymous after
    > > optimizations" variants.


    I've seen coding standards suggest just the opposite. With copy
    initialization, you'll never encounter C++'s most vexing parse.

    --
    James
     
    James Kanze, Oct 22, 2013
    #8
  9. James Kanze <> wrote:
    > On Monday, 21 October 2013 19:42:58 UTC+1, Tobias Müller wrote:
    >>>> Even more so as it is already a special case. Regarding only the syntax,
    >>>> you would expect the appropriate assignment operator to be called.

    >
    >>> There certainly won't be assignment operators used in initialization.

    >
    >> Yes, that's what I wanted to say. Syntactically it's an assignment, but in
    >> the context of a declaration it is special cased to actually mean
    >> initialization.

    >
    > Syntactically, it isn't an assignment. And assignment can only
    > occur as part of an expression, and the = sign there is *not*
    > part of any expression.


    Yes I'm inprecise. It _looks_ like an assignment and is a special case in
    the syntax. Better?

    > There are several character sequences that can be both operators
    > and punctuation, depending on context: the comma is the most
    > noted, but a single colon is also ambiguous in this regard.
    > That's obviously not an ideal situation, but it's one we have to
    > live with for historical reasons.
    >
    >> But then, why in a such convoluted way?

    >
    >>> Most coding standards suggest to write what you actually
    >>> want 'A a(2);' and to avoid writing "likely synonymous after
    >>> optimizations" variants.

    >
    > I've seen coding standards suggest just the opposite. With copy
    > initialization, you'll never encounter C++'s most vexing parse.


    But that still does not explain why
    A a = 2;
    is interpreted as
    A a(A(2));
    and not just
    A a(2);

    Tobi
     
    Tobias Müller, Oct 22, 2013
    #9
  10. somenath

    Öö Tiib Guest

    On Tuesday, 22 October 2013 20:43:58 UTC+3, James Kanze wrote:
    > > > want 'A a(2);' and to avoid writing "likely synonymous after
    > > > optimizations" variants.

    >
    > I've seen coding standards suggest just the opposite. With copy
    > initialization, you'll never encounter C++'s most vexing parse.


    Ok, that makes perfect sense without tools that can warn about likely
    most vexing parse. How often does anyone actually want to declare a
    function in other function's body? I have had very close to zero
    occasions of such desire. So most vexing parse is accidental usage
    of useless feature and a tool that underlines it with red does
    not take any rocket science to develop.
     
    Öö Tiib, Oct 22, 2013
    #10
  11. somenath

    Rosario1903 Guest

    On Tue, 22 Oct 2013 18:13:01 +0000 (UTC), Tobias Müller
    <> wrote:

    >James Kanze <> wrote:
    >> On Monday, 21 October 2013 19:42:58 UTC+1, Tobias Müller wrote:
    >>>>> Even more so as it is already a special case. Regarding only the syntax,
    >>>>> you would expect the appropriate assignment operator to be called.

    >>
    >>>> There certainly won't be assignment operators used in initialization.

    >>
    >>> Yes, that's what I wanted to say. Syntactically it's an assignment, but in
    >>> the context of a declaration it is special cased to actually mean
    >>> initialization.

    >>
    >> Syntactically, it isn't an assignment. And assignment can only
    >> occur as part of an expression, and the = sign there is *not*
    >> part of any expression.

    >
    >Yes I'm inprecise. It _looks_ like an assignment and is a special case in
    >the syntax. Better?
    >
    >> There are several character sequences that can be both operators
    >> and punctuation, depending on context: the comma is the most
    >> noted, but a single colon is also ambiguous in this regard.
    >> That's obviously not an ideal situation, but it's one we have to
    >> live with for historical reasons.
    >>
    >>> But then, why in a such convoluted way?

    >>
    >>>> Most coding standards suggest to write what you actually
    >>>> want 'A a(2);' and to avoid writing "likely synonymous after
    >>>> optimizations" variants.

    >>
    >> I've seen coding standards suggest just the opposite. With copy
    >> initialization, you'll never encounter C++'s most vexing parse.

    >
    >But that still does not explain why
    >A a = 2;
    >is interpreted as
    >A a(A(2));
    >and not just
    >A a(2);


    >Tobi


    A a=2;

    would be:
    A::a() or don't know how they say that default constructor for A
    applied on "a" with 0 arg
    a=2 assign to "a" the value 2
     
    Rosario1903, Oct 23, 2013
    #11
  12. somenath

    Rosario1903 Guest

    On Wed, 23 Oct 2013 08:54:02 +0200, Rosario1903
    <> wrote:

    >On Tue, 22 Oct 2013 18:13:01 +0000 (UTC), Tobias Müller
    ><> wrote:
    >
    >>James Kanze <> wrote:
    >>But that still does not explain why
    >>A a = 2;
    >>is interpreted as
    >>A a(A(2));
    >>and not just
    >>A a(2);

    >
    >>Tobi

    >
    >A a=2;
    >
    >would be:
    >A::a() or don't know how they say that default constructor for A

    ^^^^^^^^^^^
    constructor for A applied on "a" with 0 arg

    > applied on "a" with 0 arg


    >a=2 assign to "a" the value 2


    with operator=
     
    Rosario1903, Oct 23, 2013
    #12
  13. somenath

    Öö Tiib Guest

    On Wednesday, 23 October 2013 09:54:02 UTC+3, Rosario1903 wrote:
    > On Tue, 22 Oct 2013 18:13:01 +0000 (UTC), Tobias M�ller
    > <> wrote:
    > >But that still does not explain why
    > >A a = 2;
    > >is interpreted as
    > >A a(A(2));
    > >and not just
    > >A a(2);

    >
    > A a=2;
    >
    > would be:
    >
    > A::a() or don't know how they say that default constructor for A
    > applied on "a" with 0 arg
    > a=2 assign to "a" the value 2


    Are you suggesting such change? If you suggest it as change then that won'thappen. Silent
    change of behaviour won't be accepted into C++.

    What Tobias suggests is what most C++ compilers do anyway because it is allowed. So I
    also think that ... why not?
     
    Öö Tiib, Oct 23, 2013
    #13
  14. somenath

    Öö Tiib Guest

    On Wednesday, 23 October 2013 11:23:47 UTC+3, Juha Nieminen wrote:
    > ?? Tiib <> wrote:
    > > There certainly won't be assignment operators used in initialization. Most
    > > coding standards suggest to write what you actually want 'A a(2);' and
    > > to avoid writing "likely synonymous after optimizations" variants.

    >
    > Then you get problems like this:
    >
    > struct A { ... };
    > struct Comparator { bool operator()(const A&, const A&) const { ... } };
    >
    > std::map<A, int, Comparator> theMap(Comparator());


    Should add double parentheses somewhere:

    std::map<A, int, Comparator> theMap((Comparator()));

    > (Can't see what the problem is? Try calling one of the member functions
    > of theMap...)


    The people who don't see it with bare eye should use -Wvexing-parse of clang.
    I'm still thinking that there is powerful enemy rat in standard commission. Every
    time they mess with initialisation they add more confusing and ambiguous
    syntaxes. The new 'A a{2};' and 'A a = {2};' are screwed up as well.
     
    Öö Tiib, Oct 23, 2013
    #14
  15. Rosario1903 <> wrote:
    > On Wed, 23 Oct 2013 08:54:02 +0200, Rosario1903
    > <> wrote:
    >
    >> On Tue, 22 Oct 2013 18:13:01 +0000 (UTC), Tobias Müller
    >> <> wrote:
    >>
    >>> James Kanze <> wrote:
    >>> But that still does not explain why
    >>> A a = 2;
    >>> is interpreted as
    >>> A a(A(2));
    >>> and not just
    >>> A a(2);

    >>
    >>> Tobi

    >>
    >> A a=2;
    >>
    >> would be:
    >> A::a() or don't know how they say that default constructor for A

    > ^^^^^^^^^^^
    > constructor for A applied on "a" with 0 arg
    >
    >> applied on "a" with 0 arg

    >
    >> a=2 assign to "a" the value 2

    >
    > with operator=


    We're going in circles.
    Even if it looks like an assignment, it is in fact initialization. There is
    no operator= involved.

    I understand that this is legacy from C. What I don't understand is why
    they chose copy initialization instead of direct initialization.

    Tobi
     
    Tobias Müller, Oct 23, 2013
    #15
  16. Juha Nieminen <> wrote:
    > ?? Tiib <> wrote:
    >> There certainly won't be assignment operators used in initialization. Most
    >> coding standards suggest to write what you actually want 'A a(2);' and
    >> to avoid writing "likely synonymous after optimizations" variants.

    >
    > Then you get problems like this:
    >
    > struct A { ... };
    > struct Comparator { bool operator()(const A&, const A&) const { ... } };
    >
    > std::map<A, int, Comparator> theMap(Comparator());
    >
    > (Can't see what the problem is? Try calling one of the member functions
    > of theMap...)


    Actually, I can't right now. I have also no compiler at hand.

    But I don't see how it would be relevant either. I was not proposing a
    macro-like (text based) expansion from:
    A a = 2;
    To:
    A a(2);

    The second form would never occur in the source and wouldn't have to be
    parsed.
    What I proposed was to interpret:
    A a = 2;
    as:
    "Call of a suitable constructor with the RHS as direct argument"

    Tobi
     
    Tobias Müller, Oct 23, 2013
    #16
  17. somenath

    Rosario1903 Guest

    On Wed, 23 Oct 2013 09:47:12 +0000 (UTC), Tobias Müller
    <> wrote:

    >Rosario1903 <> wrote:
    >> On Wed, 23 Oct 2013 08:54:02 +0200, Rosario1903
    >> <> wrote:
    >>
    >>> On Tue, 22 Oct 2013 18:13:01 +0000 (UTC), Tobias Müller
    >>> <> wrote:
    >>>
    >>>> James Kanze <> wrote:
    >>>> But that still does not explain why
    >>>> A a = 2;
    >>>> is interpreted as
    >>>> A a(A(2));
    >>>> and not just
    >>>> A a(2);
    >>>
    >>>> Tobi
    >>>
    >>> A a=2;
    >>>
    >>> would be:
    >>> A::a() or don't know how they say that default constructor for A

    >> ^^^^^^^^^^^
    >> constructor for A applied on "a" with 0 arg
    >>
    >>> applied on "a" with 0 arg

    >>
    >>> a=2 assign to "a" the value 2

    >>
    >> with operator=

    >
    >We're going in circles.
    >Even if it looks like an assignment, it is in fact initialization. There is
    >no operator= involved.
    >
    >I understand that this is legacy from C. What I don't understand is why
    >they chose copy initialization instead of direct initialization.


    is it so, because one *see* the same that is executed?
    int a=3;
    would mean reserve mem for a, and fill with 3 value
    in C++=> use one constructor for a, and use operator= for copy that

    if i like to use copy constructor i would use A b,a(b);
    if i like to use constructor int A a(2);
    if i like to use A::A() constructor and operator=(int ) A a=2
    etc

    but i know that all is already done, and C++ already call all i not
    remember because i not study all that and i not have very very good
    memory etc

    >Tobi
     
    Rosario1903, Oct 23, 2013
    #17
  18. "K. Frank" <> wrote:
    > Hi Alf!
    >
    > On Monday, October 21, 2013 12:37:04 AM UTC-4, Alf P. Steinbach wrote:
    >> On 21.10.2013 06:15, somenath wrote:
    >>
    >>> The copy constructor is not getting called. Where am I going wrong?

    >> ...
    >> Thus, when you have a declaration like
    >>
    >> A a = 2;
    >>
    >> then the formal meaning is
    >>
    >> A a( A( 2 ) );
    >>
    >> that is, a copy construction.
    >>
    >> But while that means that the copy constructor must be ACCESSIBLE, the
    >> compiler is allowed to optimize this to
    >>
    >> A a( 2 );
    >>
    >> that is, a direct initialization, even if that fails to produce some
    >> intended side effect in the copy constructor.

    >
    > I agree that this is the case, but I've often
    > wondered why.
    >
    > Given that in somenath's example, the constructor
    > A(int) exists, and given that the compiler is
    > allowed to copy-elide the copy constructor away,
    > why does the standard _not_ define
    >
    > A a = 2;
    >
    > and
    >
    > A a(2);
    >
    > to be synonymous? That is, why not just define
    > A a = 2 to be direct initialization, and be done
    > with it?
    >
    > Given that the programmer cannot rely on the copy
    > constructor getting called in this situation, I
    > don't see any reason why letting the compiler
    > first construct and then copy construct would be
    > advantage. Wouldn't it be simpler and better (and
    > fully backward compatible) just to require A a = 2
    > to be direct initialization?


    Could it be that:
    B b;
    A a = b;
    is not actually equivalent to:
    B b;
    A a(A(b));
    but rather to:
    "Explicitly call the copy constructor of A with b as argument."
    which is equivalent to:
    A a(implicit_cast<const A&>(b));

    This would also take conversion operators into account, not only conversion
    constructors.

    implicit_cast would be defined as:
    template<typename A>
    A implicit_cast(A a) { return a; }
    or similar

    Tobi
     
    Tobias Müller, Oct 24, 2013
    #18
  19. somenath

    K. Frank Guest

    Hello Tobi!

    On Thursday, October 24, 2013 12:12:58 PM UTC-4, Tobias Müller wrote:
    > "K. Frank" <> wrote:
    > > Hi Alf!
    > >
    > > On Monday, October 21, 2013 12:37:04 AM UTC-4, Alf P. Steinbach wrote:
    > >> ...
    > >> Thus, when you have a declaration like
    > >>
    > >> A a = 2;
    > >>
    > >> then the formal meaning is
    > >>
    > >> A a( A( 2 ) );
    > >>
    > >> that is, a copy construction.
    > >>
    > >> But while that means that the copy constructor must be ACCESSIBLE, the
    > >> compiler is allowed to optimize this to
    > >>
    > >> A a( 2 );
    > >>
    > >> that is, a direct initialization, even if that fails to produce some
    > >> intended side effect in the copy constructor.

    > > ...
    > > That is, why not just define
    > > A a = 2 to be direct initialization, and be done
    > > with it?

    > ...
    > Could it be that:
    >
    > B b;
    > A a = b;
    > is not actually equivalent to:
    > B b;
    > A a(A(b));
    > but rather to:
    > "Explicitly call the copy constructor of A with b as argument."
    > which is equivalent to:
    > A a(implicit_cast<const A&>(b));
    >
    > This would also take conversion operators into account, not only conversion
    > constructors.
    > ...


    I think you're probably right about this. (At least
    it sounds good.)

    Just to be clear, what I think you're saying is that
    if the conversion operator:

    B::eek:perator A()

    exists, but the constructor:

    A::A(B)

    does not, then (as currently defined)

    A a = b;

    will work, because the conversion operator exists,
    but if we defined A a = b; to be exactly synonymous
    with direct initialization, then it would fail,
    because the necessary constructor doesn't exist.

    Is that right?

    (Perhaps I will take a look at the standard and/or
    write a test program to sort this out.)

    By the way, this may be relevant to the recent post
    "Understanding copy construction ambiguity" on our
    moderated companion group:

    https://groups.google.com/forum/?fromgroups#!topic/comp.lang.c .moderated/-5pL9ywO29Y

    Perhaps somebody who understands this better than I
    do could shed some light on that fellow's question.

    > Tobi



    Thanks.


    K. Frank
     
    K. Frank, Oct 24, 2013
    #19
  20. "K. Frank" <> wrote:
    > Hello Tobi!
    >
    > On Thursday, October 24, 2013 12:12:58 PM UTC-4, Tobias Müller wrote:
    >> "K. Frank" <> wrote:
    >>> Hi Alf!
    >>>
    >>> On Monday, October 21, 2013 12:37:04 AM UTC-4, Alf P. Steinbach wrote:
    >>>> ...
    >>>> Thus, when you have a declaration like
    >>>>
    >>>> A a = 2;
    >>>>
    >>>> then the formal meaning is
    >>>>
    >>>> A a( A( 2 ) );
    >>>>
    >>>> that is, a copy construction.
    >>>>
    >>>> But while that means that the copy constructor must be ACCESSIBLE, the
    >>>> compiler is allowed to optimize this to
    >>>>
    >>>> A a( 2 );
    >>>>
    >>>> that is, a direct initialization, even if that fails to produce some
    >>>> intended side effect in the copy constructor.
    >>> ...
    >>> That is, why not just define
    >>> A a = 2 to be direct initialization, and be done
    >>> with it?

    >> ...
    >> Could it be that:
    >>
    >> B b;
    >> A a = b;
    >> is not actually equivalent to:
    >> B b;
    >> A a(A(b));
    >> but rather to:
    >> "Explicitly call the copy constructor of A with b as argument."
    >> which is equivalent to:
    >> A a(implicit_cast<const A&>(b));
    >>
    >> This would also take conversion operators into account, not only conversion
    >> constructors.
    >> ...

    >
    > I think you're probably right about this. (At least
    > it sounds good.)
    >
    > Just to be clear, what I think you're saying is that
    > if the conversion operator:
    >
    > B::eek:perator A()
    >
    > exists, but the constructor:
    >
    > A::A(B)
    >
    > does not, then (as currently defined)
    >
    > A a = b;
    >
    > will work, because the conversion operator exists,
    > but if we defined A a = b; to be exactly synonymous
    > with direct initialization, then it would fail,
    > because the necessary constructor doesn't exist.
    >
    > Is that right?


    That's what I was thinking, though I am not a language lawyer.

    > (Perhaps I will take a look at the standard and/or
    > write a test program to sort this out.)
    >
    > By the way, this may be relevant to the recent post
    > "Understanding copy construction ambiguity" on our
    > moderated companion group:
    >
    > https://groups.google.com/forum/?fromgroups#!topic/comp.lang.c .moderated/-5pL9ywO29Y


    Yeah, reading that post actually made me thinking in that direction.

    > Perhaps somebody who understands this better than I
    > do could shed some light on that fellow's question.


    I would have to think a bit more about it.

    Tobi
     
    Tobias Müller, Oct 24, 2013
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VisionSet
    Replies:
    8
    Views:
    4,927
    Tris Orendorff
    Apr 29, 2004
  2. Aire
    Replies:
    3
    Views:
    474
    Mike Wahler
    Jan 25, 2004
  3. ali
    Replies:
    4
    Views:
    590
    David Harmon
    Mar 5, 2007
  4. Generic Usenet Account
    Replies:
    10
    Views:
    2,282
  5. cinsk
    Replies:
    35
    Views:
    2,652
    James Kanze
    Oct 11, 2010
Loading...

Share This Page