Is it simply preference or are there specific instances where one is necessary over another? I'm refering to the foll开发者_JS百科owing variants for initialization
T t(e); // direct initialization
T t = e; // copy initialization
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 theTest
constructor for implicit conversion was disallowed by theexplicit
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.,
精彩评论