copy initialization and direct initialization from C++ Primer

Discussion in 'C++' started by pauldepstein@att.net, Mar 25, 2009.

  1. Guest

    From page 477 of 4th edition of C++ Primer.
    "Direct-initialization directly invokes the constructor matched by the
    arguments. Copy-initialization always involves the copy-constructor."

    It occurs to me that the "constructor matched by the arguments" might
    be the copy-constructor. In this case, I would think copy-
    initialization and direct-initialization are exactly the same. My
    concern (and reason for this posting) is that I haven't seen anyone
    say the same thing.

    For example, does std::string null_book = "99"; mean the same
    as std::string null_book("99"); ? (On my compiler, they behave the
    same way.) And would the behaviour always be the same if std::string
    is replaced by another class?

    Paul Epstein
    , Mar 25, 2009
    #1
    1. Advertising

  2. wrote:
    > From page 477 of 4th edition of C++ Primer.
    > "Direct-initialization directly invokes the constructor matched by the
    > arguments. Copy-initialization always involves the copy-constructor."
    >
    > It occurs to me that the "constructor matched by the arguments" might
    > be the copy-constructor. In this case, I would think copy-
    > initialization and direct-initialization are exactly the same. My
    > concern (and reason for this posting) is that I haven't seen anyone
    > say the same thing.


    You're just picking on words, aren't you? If the constructor "matched
    by the arguments" is the copy-constructor, then the initialisation is in
    fact *copy-initialisation*, isn't it?

    > For example, does std::string null_book = "99"; mean the same
    > as std::string null_book("99"); ?


    No. The former is copy-initialisation. The array "99" degrades to the
    pointer to its first character, and then a temporary is constructed,
    from which the 'null_book' is constructed. So, 'null_book' is
    copy-initialised (in this case). Those are the semantics, anyway. The
    compiler is *allowed* to skip creating the temporary in that case, but
    the copy constructor has to be *accessible*, *as if* the copy is
    actually created.

    > (On my compiler, they behave the
    > same way.) And would the behaviour always be the same if std::string
    > is replaced by another class?


    Yes. For example,

    class my_noncopyable_string {
    my_noncopyable_string(const my_noncopyable_string&); // private
    public:
    my_noncopyable_string(const char*);
    };

    int main() {
    my_noncopyable_string foo = "99";
    }

    shouldn't compile, but

    ...
    my_noncopyable_string bar("99");

    should.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Mar 25, 2009
    #2
    1. Advertising

  3. wrote:
    > From page 477 of 4th edition of C++ Primer.
    > "Direct-initialization directly invokes the constructor matched by the
    > arguments. Copy-initialization always involves the copy-constructor."
    >
    > It occurs to me that the "constructor matched by the arguments" might
    > be the copy-constructor. In this case, I would think copy-
    > initialization and direct-initialization are exactly the same. My
    > concern (and reason for this posting) is that I haven't seen anyone
    > say the same thing.


    Well, I believe it has been said here many times. According to the
    language specification, when the object type and the initializer type
    are the same (ignoring any CV-qualification), both initializations works
    in exactly the same way (is copy-initialization follows exactly the same
    algorithm as direct-initialization).

    > For example, does std::string null_book = "99"; mean the same
    > as std::string null_book("99"); ?


    No, of course not. But what does this have to do with your original
    question? Your question was about situation when copy constructor is
    selected by direct-initialization. In this example direct-initialization
    _does_ _not_ select copy constructor. Instead, it will use conversion
    constructor from 'const char*'. So, what is this example is doing here?

    > (On my compiler, they behave the same way.)


    I'm not sure what you mean by "the same" here, but if they indeed behave
    exactly the same way, this might be the effect of compiler optimization.
    From the abstract C++ point of view the first version calls copy
    constructor (just like you said above), while the second does not. I.e.
    they don't behave the same way.

    > And would the behaviour always be the same if std::string
    > is replaced by another class?


    It is hard to understand what you are trying to ask, since the example
    you are referring to does not match the original question you were
    asking. Please, clarify your question.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Mar 25, 2009
    #3
  4. James Kanze Guest

    On Mar 25, 1:05 pm, wrote:
    > From page 477 of 4th edition of C++ Primer.
    > "Direct-initialization directly invokes the constructor
    > matched by the arguments. Copy-initialization always involves
    > the copy-constructor."


    > It occurs to me that the "constructor matched by the
    > arguments" might be the copy-constructor. In this case, I
    > would think copy- initialization and direct-initialization are
    > exactly the same. My concern (and reason for this posting) is
    > that I haven't seen anyone say the same thing.


    The distinction between copy-initialization and
    direct-initialization is one of syntax:
    T v = x ;
    is copy initialization,
    T v( x ) ;
    is direct initialization, regardless of what constructors
    ultimately get called. The standard does distinguish the case
    where the initializing type in copy initialization has the same
    type (modulo cv-qualifiers) as the type being initialized, in
    order to make it clear that the copy constructor can't be called
    twice. The basic rules are: direct initialization and copy
    initialization where the type of the initializing expression is
    the same as that of the initialized object: find an appropriate
    constructor and call it; copy initialization where the
    initialization expression has a different type, convert that
    type to the target type, then find an appropriate constructor
    (using operator overload resolution---and there are cases where
    the appropriate constructor won't be the copy constructor) and
    call it.

    > For example, does std::string null_book = "99"; mean the same
    > as std::string null_book("99"); ?


    The final results will be the same, because of the semantics of
    std::string. Formally, however, the first is the equivalent of:

    std::string null_book( std::string( "99" ) ) ;

    The compiler is allowed to optimize the intermediate temporary
    out, but only if the program would be legal before the
    optimization.

    > (On my compiler, they behave the same way.) And would the
    > behaviour always be the same if std::string is replaced by
    > another class?


    For most classes, you won't see a difference. Provide a private
    copy constructor, and copy initialization will cause an error at
    compile time. Provide a conversion operator in the
    initialization type, but no constructor using that type in the
    target type, and copy initialization will be legal, but not
    direct initialization.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Mar 26, 2009
    #4
  5. James Kanze Guest

    On Mar 25, 1:23 pm, Victor Bazarov <> wrote:
    > wrote:
    > > From page 477 of 4th edition of C++ Primer.
    > > "Direct-initialization directly invokes the constructor
    > > matched by the arguments. Copy-initialization always
    > > involves the copy-constructor."


    > > It occurs to me that the "constructor matched by the
    > > arguments" might be the copy-constructor. In this case, I
    > > would think copy- initialization and direct-initialization
    > > are exactly the same. My concern (and reason for this
    > > posting) is that I haven't seen anyone say the same thing.


    > You're just picking on words, aren't you? If the constructor
    > "matched by the arguments" is the copy-constructor, then the
    > initialisation is in fact *copy-initialisation*, isn't it?


    No. Copy initialization refers to the syntax, not which
    constructor is called.

    If you really want to pick on words: the copy constructor has
    nothing to do with anything here. The only particularity of the
    copy constructor is that the compiler will generate one if the
    programmer doesn't declare one. The signature of the copy
    constructor is such that it will often be chosen by overload
    resolution when copying (whence the name), but formally, it has
    no special role here---the compiler applies overload resolution,
    as usual.

    > > For example, does std::string null_book = "99"; mean the same
    > > as std::string null_book("99"); ?


    > No. The former is copy-initialisation. The array "99"
    > degrades to the pointer to its first character, and then a
    > temporary is constructed, from which the 'null_book' is
    > constructed. So, 'null_book' is copy-initialised (in this
    > case). Those are the semantics, anyway. The compiler is
    > *allowed* to skip creating the temporary in that case, but the
    > copy constructor has to be *accessible*, *as if* the copy is
    > actually created.


    And the semantics of std::string are such that you can't tell
    whether the compiler has skipped the temporary or not, so
    ultimately, the two do mean the same thing.

    > > (On my compiler, they behave the same way.) And would the
    > > behaviour always be the same if std::string is replaced by
    > > another class?


    > Yes. For example,


    You mean no, of course (since you give an example where the
    behavior isn't the same).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Mar 26, 2009
    #5
  6. Arne Mertz Guest

    James Kanze schrieb:
    > For most classes, you won't see a difference. Provide a private
    > copy constructor, and copy initialization will cause an error at
    > compile time. Provide a conversion operator in the
    > initialization type, but no constructor using that type in the
    > target type, and copy initialization will be legal, but not
    > direct initialization.


    Yes, direct initialization _will_ be legal. As with the call of any
    normal function the compiler will try to implicitly convert the
    argument in another type that fits the function's (i.e. the
    constructor's) parameter.

    greets
    Arne
    Arne Mertz, Mar 26, 2009
    #6
    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. , India
    Replies:
    3
    Views:
    310
    Neelesh Bodas
    Jul 3, 2007
  2. , India
    Replies:
    2
    Views:
    1,101
    terminator
    Nov 23, 2007
  3. , India
    Replies:
    3
    Views:
    375
    prashanta
    Dec 30, 2008
  4. , India
    Replies:
    5
    Views:
    402
    James Kanze
    Aug 21, 2009
  5. Taras_96
    Replies:
    3
    Views:
    585
    Michael Tsang
    Oct 30, 2009
Loading...

Share This Page