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 MyClass<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?
You can initialize any auto variable except function parameters. If you do not explicitly initialize an automatic object, its value is indeterminate. If you provide an initial value, the expression representing the initial value can be any valid C or C++ expression.
Automatic initialization in JavaJava does not initialize non-array local variables (also referred to as automatic variables) . The Java compiler generates error messages when it detects attempts to use uninitialized local variables. The Initializer program shows how automatic initialization works.
Without an explicit initializer, automatic objects are default-initialized. Objects of class type with a default constructor are default-initialized by calling the default constructor. Objects of class type without a default constructor and objects of built-in type are left uninitialized by default initialization.
In computer programming, initialization (or initialisation) is the assignment of an initial value for a data object or variable. The manner in which initialization is performed depends on the programming language, as well as the type, storage class, etc., of an object to be initialized.
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{};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With