16
int value = 5; // this type of assignment is called an explicit assignment
int value(5); // this type of assignment is called an implicit assignment

What is the difference between those, if any, and in what cases do explicit and implicit assignment differ and how?


http://weblogs.asp.net/kennykerr/archive/2004/08/31/Explicit-Constructors.aspx

EDIT: I actually just found this article, which makes the whole thing a lot clearer... and it brings up another question, should you (in general) mark constructors taking a single parameter of a primitive type - numeric/bool/string - as explicit and leave the rest as they are (of course keeping watch for gotchas such as constructors like (int, SomeType = SomeType())?

Jake Petroules
  • 23,472
  • 35
  • 144
  • 225
  • 3
    This smells like homework. If it is, please tag it as such. – greyfade Jun 16 '10 at 23:22
  • Not homework, just a note I had from a long time ago that I never investigated. What does tagging something as homework do, anyways? – Jake Petroules Jun 16 '10 at 23:31
  • 1
    It makes it clear the question is homework. =] Typically, people answering the question will prefer giving hints to providing the entire answer. – strager Jun 16 '10 at 23:36
  • 2
    Just for the record, I have this question, and it's not homework. :) Just a point on the learning curve, I suppose. – Ben Aug 25 '12 at 03:15

3 Answers3

21

Neither of these is an assignment of any kind -- they're both initialization. The first uses copy initialization, and the second direct initialization. (FWIW, I'm pretty sure I've never heard the terms "explicit assignment" or "implicit assignment" before).

Edit: (Mostly in response to Nathan's comment):

Here's a corrected version of the code from your comment:

#include <iostream>

struct Foo { 
    Foo() { 
        std::cout << "Foo::ctor()" << std::endl; 
    } 
    Foo(Foo const& copy) { 
        std::cout << "Foo::cctor()" << std::endl; 
    } 
    Foo& operator=(Foo const& copy) { 
        std::cout << "foo::assign()" << std::endl; 
        return *this; 
    } 
};

int main(int, const char**) { 
    Foo f; 
    Foo b(f); 
    Foo x = b;
    return 0; 
}

The result from running this should be:

Foo::ctor()
Foo::cctor()
Foo::cctor()

If you run it and get an foo::assign(), throw your compiler away and get one that works (oh, and let us know what compiler it is that's so badly broken)!

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Not *necessarily* true. With a POD type, yes, your statement is accurate. If the type in question was user defined, it's perfectly possible that there's a user-defined assignment operator that does the conversion without there being a similar copy constructor. Odd, yes. However, possible. – Nathan Ernst Jun 16 '10 at 23:41
  • Also, the first is assignment. Only the second is initialization. That the first can and will almost assuredly be inlined to an equivalent copy initialization does not detract from it being an assignment. The assumption that copy initialization and copy assignment are the same is flawed and is not guaranteed. – Nathan Ernst Jun 16 '10 at 23:43
  • 5
    @Nathan: This answer is correct. §8.5/12 defines "copy-initialization" to be any initialization of the form `T x = a;`, and "direct-initialization" to be any initialization of the form `T x(a);`. Both are initialization. – GManNickG Jun 16 '10 at 23:53
  • @Nathan, You have it backwards. Foo bar = baz; will never result in an assignment (unless a constructor happens to be implemented in terms of operator=), it is always copy initialization. It will at most result in code equivalent to `Foo bar(static_cast(baz));` and at least result in code equivalent to `Foo bar(baz);`. It will never result in code equivalent to `Foo bar; bar = baz;`. In other words, there is no assignment going on. See section 8.5 14-16 of the draft C++0x standard (N3092) (citing this because I don't have a copy of the current standard but this hasn't changed). – Logan Capaldo Jun 17 '10 at 00:04
  • @Nathan Ernst: Absolutely incorrect. Neither form will ever call the assignment operator. These initialization are always handled by constructors (possibly involving conversion operators), but if some constructor is missing the code will not compile. Assignment will never be used instead. – AnT stands with Russia Jun 17 '10 at 00:07
  • explain this, then: #include struct Foo { Foo() { std::cout << "Foo::ctor()" << std::endl; } Foo(Foo const& copy) { std::cout << "Foo::cctor()" << std::endl; } Foo& operator=(Foo const& copy) { std::cout << "foo::assign()" << std::endl; return *this; } }; int main(int, const char**) { Foo f; Foo b(f); b = Foo(); return 0; Foo::ctor() Foo::cctor() Foo::ctor() foo::assign() – Nathan Ernst Jun 17 '10 at 00:19
  • There is literally an assumption that copy and assignment are functionally equivalent, and the standard does not guarantee this is so. While it is generally so, it is not necessarily so. To arbitrarily make this assumption is incorrect. A compiler can only safely make this assumption when the net results of the two operations are the same (which is actually verifiable). – Nathan Ernst Jun 17 '10 at 00:23
  • No one is making the assumption that copy and assignment are functionally equivalent, what you fail to understand is that `T a = b` is _not_ an assignment. Assignment doesn't mean `=` appears in the expression. Specifically, `int value = 5` from the OP is not an assignment as you erroneously state in your comment. Nor will overloading an assignment operator make `T a = b` into an assignment. Add a line like `Foo c = f;` to your example and see if it prints `foo::assign()`. It will not. – Logan Capaldo Jun 17 '10 at 00:47
  • @Nathan Ernst: What do you want us to explain in your "explain this" comment? Where do you see the evidence of assignment operator being used for initialization??? The code you posted in the comment works as expected: constructor is used for initialization, assignment operator is used for assignment. You were supposed to demonstrate how assignment operator can be used in initialization. Your code doesn't demonstrate anything like that. – AnT stands with Russia Jun 17 '10 at 08:11
7

They differ if a class has a constructor marked 'explicit'. Then, one of these does not work.

Otherwise, no difference.

Pavel Radzivilovsky
  • 18,794
  • 5
  • 57
  • 67
-1

Only the first one is an assignment. They are both initialization.

Edit: actually, I'm wrong. Neither are assignment.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125