Value-initializing an automatic object?
I'm writing a template class and at one point in my code would like to be able to value-initialize an object of the parameterized type on the stack. Right now, I'm accomplishing this by writing something to this effect:
template <typename T> void MyClass<T>::doSomething() {
T valueInitialized = T();
/* ... */
}
This code works, but (unless the compiler is smart) it requires an unnecessary creation and destruction of the temporary T
object. What I'd like to write is the following, which I know is incorrect:
template <typename T> void MyCla开发者_如何学Css<T>::doSomething() {
T valueInitialized(); // WRONG: This is a prototype!
/* ... */
}
My question is whether there is a nice way to value-initialize the automatic object without having to explicitly construct a temporary object and assign it over to the automatic object. Can this be done? Or is T var = T();
as good as it gets?
The following uses copy-initialization, which is 'probably fine' 95% of the time in C++03:
T var = T();
But for generic (C++03) code, you should always prefer direct-initialization to account for that other 5%:
T var((T())); // extra parentheses avoid the most vexing parse – the extra parentheses
// force the contents to be evaluated as an expression, thus implicitly
// *not* as a declaration.
Or better yet, use the Boost.Utility.ValueInit library, which packages up the ideal behavior for you along with workarounds for various compiler deficiencies (sadly, more than one might think):
boost::value_initialized<T> var;
For C++11, one can use list-initialization syntax to achieve direct value-initialization in a significantly less noisy/ugly manner:
T var{}; // unambiguously value-initialization†
(†N.b. technically this will invoke std::initializer_list<>
constructors instead of performing value-initialization for certain pathological types. Presumably the net result should be the same.)
You can use curly braces in C++0x:
T valueInitialized{};
No, there isn't any other way to reliably value-initialize a template type in C++03.
If you can count on T
only being class types with default constructors, you could just write
T valueInitialized;
but if T
might as well be a built-in type,
T valueInitialized = T();
is the way to go.
Do you have any reason to not to trust your compiler to optimize away that copy?
精彩评论