When should you use direct initialization and when copy initialization?

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-28 06:01:31

The actual names of the things you describe is not implicit and explicit assignment but :

  • Copy-initialization : T x = a;
  • Direct-initialization : T x(a);

They are not equivalent, most notably in contexts where a conversion is required, for example when T is of class type and a is of a different type (see Alf comment for examples of contexts which don't even involve conversion). Consider the following code :

class Test
{
public:
    explicit Test(int i) { /* ... */ }
};

int main()
{
    Test t(0);  // OK : calls Test::Test(int)
    Test u = 0; // KO : constructor is marked explicit
}

To paraphrase the standard (8.5/14) :

  • For direct-initialization and copy-initialization where the source type is the same as, or a derived class of, the class of destination, constructors are considered
  • For other copy-initialization cases, like the second line of main in my example, user-defined conversion sequence are considered. As the use of the Test constructor for implicit conversion was disallowed by the explicit keyword, the second line fails to compile.

Direct initialization like

std::istringstream  stream( "blah blah" );

is necessary when the type in question, here std::istringstream from the C++ standard library, does not have an accessible copy constructor.

A copy initialization, like

std::istringstream  stream = "blah blah";   //! NOT VALID

requires an accessible copy constructor, because it's performed as if a temporary object is created on the right hand side of =, and as if that temporary is then used to initialize the variable being declared.

In the other direction, in C++98 the copy initialization syntax is needed in order to use curly braces initializers. For example, direct initialization can't be used to initialize an aggregate. But you can use copy initialization with a curly braces initializer:

#include <string>
using namespace std;

struct Answer
{
    int     nVotes;
    string  description;
};    

int main()
{
    Answer const  incorrect   = { 26, "they're the same!" };
    Answer const  correct     = { -1, "nah, they're different, actually" };
}

So, there are significant differences.

I generally prefer copy initialization syntax because of the clarity. But sometimes, as shown above, direct initialization is, unfortunately, necessary. Some people, e.g. C++ textbook author Francis Glassborow, have instead landed on direct initialization as their preferred initialization syntax (I'm not sure why, it's less clear to my eyes, and introduces the "most vexing parse" problem), and for them it's the necessity of copy initialization in some cases, that is unfortunate.

Cheers & hth.,

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!