forked from boostorg/utility
		
	
		
			
				
	
	
		
			565 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			565 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
[/
 | 
						|
 / Copyright (c) 2012 Marshall Clow
 | 
						|
 / Copyright (c) 2021, Alan Freitas
 | 
						|
 /
 | 
						|
 / Distributed under the Boost Software License, Version 1.0. (See accompanying
 | 
						|
 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
						|
 /]
 | 
						|
 | 
						|
[/===============]
 | 
						|
[#sec:value_init]
 | 
						|
[section Value Init]
 | 
						|
[/===============]
 | 
						|
 | 
						|
[heading Introduction]
 | 
						|
 | 
						|
Constructing and initializing objects in a generic way is difficult in
 | 
						|
C++. The problem is that there are several different rules that apply
 | 
						|
for initialization. Depending on the type, the value of a newly constructed
 | 
						|
object can be zero-initialized (logically 0), default-constructed (using
 | 
						|
the default constructor), or indeterminate. When writing generic code,
 | 
						|
this problem must be addressed. The template __value_initialized__ provides
 | 
						|
a solution with consistent syntax for value initialization of scalar,
 | 
						|
union and class types. Moreover, __value_initialized__ offers a workaround to various
 | 
						|
compiler issues regarding value-initialization.
 | 
						|
 | 
						|
Furthermore, a `const` object __initialized_value__ is provided,
 | 
						|
to avoid repeating the type name when retrieving the value from a
 | 
						|
`__value_initialized__<T>` object.
 | 
						|
 | 
						|
There are various ways to initialize a variable, in C++. The following
 | 
						|
declarations all ['may] have a local variable initialized to its default
 | 
						|
value:
 | 
						|
 | 
						|
```
 | 
						|
T1 var1;
 | 
						|
T2 var2 = 0;
 | 
						|
T3 var3 = {};
 | 
						|
T4 var4 = T4();
 | 
						|
```
 | 
						|
 | 
						|
Unfortunately, whether or not any of those declarations correctly
 | 
						|
initialize the variable very much depends on its type. The first
 | 
						|
declaration is valid for any __DefaultConstructible__ type by definition.
 | 
						|
 | 
						|
However, it does not always do an initialization. It correctly initializes
 | 
						|
the variable when it's an instance of a class, and the author of the class
 | 
						|
has provided a proper default constructor. On the other hand, the value of
 | 
						|
`var1` is ['indeterminate] when its type is an arithmetic type, like `int`,
 | 
						|
`float`, or `char`.
 | 
						|
 | 
						|
An arithmetic variable is of course initialized properly by the second declaration,
 | 
						|
`T2 var2 = 0`. But this initialization form will not usually work for a
 | 
						|
class type, unless the class was especially written to support being
 | 
						|
initialized that way.
 | 
						|
 | 
						|
The third form, `T3 var3 = {}`, initializes an aggregate, typically a "C-style"
 | 
						|
`struct` or a "C-style" array. However, at the time this library was developed,
 | 
						|
the syntax did not allow for a class that has an explicitly declared constructor.
 | 
						|
 | 
						|
The fourth form is the most generic form of them, as it can be used to initialize
 | 
						|
arithmetic types, class types, aggregates, pointers, and other types.
 | 
						|
The declaration,  `T4 var4 = T4()`, should be read as follows: First a temporary
 | 
						|
object is created, by `T4()`. This object is [link sec:valueinit value-initialized].
 | 
						|
Next the temporary object is copied to the named variable, `var4`. Afterwards,
 | 
						|
the temporary is destroyed. While the copying and the destruction are likely to
 | 
						|
be optimized away, C++ still requires the type `T4` to be __CopyConstructible__.
 | 
						|
So `T4` needs to be ['both] __DefaultConstructible__ ['and] __CopyConstructible__.
 | 
						|
 | 
						|
A class may not be CopyConstructible, for example because it may have a
 | 
						|
private and undefined copy constructor, or because it may be derived from
 | 
						|
`boost::noncopyable`. Scott Meyers \[[link sec:references 2]\] explains why a
 | 
						|
class would be defined like that.
 | 
						|
 | 
						|
There is another, less obvious disadvantage to the fourth form, `T4 var4 = T4()`:
 | 
						|
It suffers from various [link sec:compiler_issues compiler issues], causing
 | 
						|
a variable to be left uninitialized in some compiler specific cases.
 | 
						|
 | 
						|
The template __value_initialized__ offers a generic way to initialize
 | 
						|
an object, like `T4 var4 = T4()`, but without requiring its type
 | 
						|
to be __CopyConstructible__. And it offers a workaround to those compiler issues
 | 
						|
regarding value-initialization as well. It allows getting an initialized
 | 
						|
variable of any type; it ['only] requires the type to be __DefaultConstructible__.
 | 
						|
A properly ['value-initialized] object of type `T` is constructed by the following
 | 
						|
declaration:
 | 
						|
 | 
						|
```
 | 
						|
value_initialized<T> var;
 | 
						|
```
 | 
						|
 | 
						|
The template __initialized__ offers both value-initialization and direct-initialization.
 | 
						|
It is especially useful as a data member type, allowing the very same object
 | 
						|
to be either direct-initialized or value-initialized.
 | 
						|
 | 
						|
The `const` object __initialized_value__ allows value-initializing a variable as follows:
 | 
						|
 | 
						|
```
 | 
						|
T var = initialized_value;
 | 
						|
```
 | 
						|
 | 
						|
This form of initialization is semantically equivalent to `T4 var4 = T4()`,
 | 
						|
but robust against the aforementioned compiler issues.
 | 
						|
 | 
						|
[#sec:details]
 | 
						|
[heading Details]
 | 
						|
 | 
						|
The C++ standard \[[link sec:references 3]\] contains the definitions
 | 
						|
of `zero-initialization` and `default-initialization`. Informally, zero-initialization
 | 
						|
means that the object is given the initial value `0` converted to the type and
 | 
						|
default-initialization means that POD \[[link sec:references 4]\] types are zero-initialized,
 | 
						|
while non-POD class types are initialized with their corresponding default constructors.
 | 
						|
 | 
						|
A ['declaration] can contain an ['initializer], which specifies the
 | 
						|
object's initial value. The initializer can be just '()', which states that
 | 
						|
the object shall be value-initialized (but see below). However, if a ['declaration]
 | 
						|
has no ['initializer] and it is of a non-`const`, non-`static` POD type, the
 | 
						|
initial value is indeterminate: (see §8.5, [dcl.init], for the
 | 
						|
accurate definitions).
 | 
						|
 | 
						|
```
 | 
						|
int x; // no initializer. x value is indeterminate.
 | 
						|
__std_string__ s; // no initializer, s is default-constructed.
 | 
						|
 | 
						|
int y = int();
 | 
						|
// y is initialized using copy-initialization
 | 
						|
// but the temporary uses an empty set of parentheses as the initializer,
 | 
						|
// so it is default-constructed.
 | 
						|
// A default constructed POD type is zero-initialized,
 | 
						|
// therefore, y == 0.
 | 
						|
 | 
						|
void foo ( __std_string__ ) ;
 | 
						|
foo ( __std_string__() ) ;
 | 
						|
// the temporary string is default constructed
 | 
						|
// as indicated by the initializer ()
 | 
						|
```
 | 
						|
 | 
						|
[#sec:valueinit]
 | 
						|
[h5 value-initialization]
 | 
						|
 | 
						|
The first [@http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html Technical
 | 
						|
Corrigendum for the C++ Standard] (TC1), whose draft was released to the public in
 | 
						|
November 2001, introduced [@http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#178 Core
 | 
						|
Issue 178], among many other issues.
 | 
						|
 | 
						|
That issue introduced the new concept of `value-initialization`, and also fixed the
 | 
						|
wording for zero-initialization. Informally, value-initialization is similar to
 | 
						|
default-initialization with the exception that in some cases non-static data members
 | 
						|
and base class sub-objects are also value-initialized.
 | 
						|
 | 
						|
The difference is that an object that is value-initialized will not have, or at least
 | 
						|
is less likely to have, indeterminate values for data members and base class sub-objects;
 | 
						|
unlike the case of an object default constructed (see Core Issue 178 for a
 | 
						|
normative description).
 | 
						|
 | 
						|
In order to specify value-initialization of an object we need to use the
 | 
						|
empty-set initializer: `()`.
 | 
						|
 | 
						|
As before, a declaration with no initializer specifies default-initialization,
 | 
						|
and a declaration with a non-empty initializer specifies copy (`=xxx`) or
 | 
						|
direct (`xxx`) initialization.
 | 
						|
 | 
						|
```
 | 
						|
template<class T> void eat(T);
 | 
						|
 | 
						|
int x ; // indeterminate initial value.
 | 
						|
 | 
						|
__std_string__ s; // default-initialized.
 | 
						|
 | 
						|
eat ( int() ) ; // value-initialized
 | 
						|
 | 
						|
eat ( __std_string__() ) ; // value-initialized
 | 
						|
```
 | 
						|
 | 
						|
[#sec:valueinitsyn]
 | 
						|
[h5 value-initialization syntax]
 | 
						|
 | 
						|
Value initialization is specified using `()`. However, the empty set of
 | 
						|
parentheses is not permitted by the syntax of initializers because it is
 | 
						|
parsed as the declaration of a function taking no arguments:
 | 
						|
 | 
						|
```
 | 
						|
int x() ; // declares function int(*)()
 | 
						|
```
 | 
						|
 | 
						|
Thus, the empty `()` must be put in some other initialization context.
 | 
						|
 | 
						|
One alternative is to use copy-initialization syntax:
 | 
						|
 | 
						|
```
 | 
						|
int x = int();
 | 
						|
```
 | 
						|
 | 
						|
This works perfectly fine for POD types. But for non-POD class types,
 | 
						|
copy-initialization searches for a suitable constructor, which could be,
 | 
						|
for instance, the copy-constructor. It also searches for a suitable conversion
 | 
						|
sequence but this does not apply in this context.
 | 
						|
 | 
						|
For an arbitrary unknown type, using this syntax may not have the
 | 
						|
value-initialization effect intended because we don't know if a copy
 | 
						|
from a default constructed object is exactly the same as a default
 | 
						|
constructed object, and the compiler is allowed, in
 | 
						|
some cases, but never required to, optimize the copy away.
 | 
						|
 | 
						|
One possible generic solution is to use value-initialization of a non static
 | 
						|
data member:
 | 
						|
 | 
						|
```
 | 
						|
template<class T>
 | 
						|
struct W
 | 
						|
{
 | 
						|
    // value-initialization of 'data' here.
 | 
						|
    W() : data() {}
 | 
						|
 | 
						|
    T data;
 | 
						|
};
 | 
						|
 | 
						|
W<int> w;
 | 
						|
// w.data is value-initialized for any type.
 | 
						|
```
 | 
						|
 | 
						|
This is the solution as it was supplied by earlier versions of the
 | 
						|
`__value_initialized__<T>` template class. Unfortunately this approach
 | 
						|
suffered from various compiler issues.
 | 
						|
 | 
						|
[#sec:compiler_issues]
 | 
						|
[h5 Compiler issues]
 | 
						|
 | 
						|
Various compilers have not yet fully implemented value-initialization.
 | 
						|
So when an object should be ['value-initialized] according to the C++ Standard,
 | 
						|
it ['may] in practice still be left uninitialized, because of those
 | 
						|
compiler issues. It is hard to make a general statement on what those issues
 | 
						|
are like, because they depend on the compiler you are using, its version number,
 | 
						|
and the type of object you would like to have value-initialized.
 | 
						|
 | 
						|
All compilers we have tested so far support value-initialization for arithmetic types properly.
 | 
						|
However, various compilers may leave some types of ['aggregates] uninitialized, when they
 | 
						|
should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
 | 
						|
go wrong on various compilers.
 | 
						|
 | 
						|
At the moment of writing, May 2010, the following reported issues regarding
 | 
						|
value-initialization are still there in current compiler releases:
 | 
						|
 | 
						|
 | 
						|
 | 
						|
* [@https://connect.microsoft.com/VisualStudio/feedback/details/100744 Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression]: Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005.
 | 
						|
* [@http://connect.microsoft.com/VisualStudio/feedback/details/484295 Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor] Reported by Sylvester Hesp, 2009.
 | 
						|
* [@https://connect.microsoft.com/VisualStudio/feedback/details/499606 Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization] Reported by Alex Vakulenko, 2009
 | 
						|
* [@http://qc.embarcadero.com/wc/qcmain.aspx?d=83751 Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized] Reported by Niels Dekker (LKEB), 2010.
 | 
						|
* [@http://qc.embarcadero.com/wc/qcmain.aspx?d=83851 Embarcadero/C++Builder Report 83851, Value-initialized temporary triggers internal backend error C1798] Reported by Niels Dekker, 2010.
 | 
						|
* [@http://qc.embarcadero.com/wc/qcmain.aspx?d=84279 Embarcadero/C++Builder Report 84279, Internal compiler error (F1004), value-initializing member function pointer by "new T()"] Reported by Niels Dekker, 2010
 | 
						|
* Sun CR 6947016, Sun 5.10 may fail to value-initialize an object of a non-POD aggregate. Reported to Steve Clamage by Niels Dekker, 2010.
 | 
						|
* IBM's XL V10.1 and V11.1 may fail to value-initialize a temporary of a non-POD aggregate. Reported to Michael Wong by Niels Dekker, 2010.
 | 
						|
* Intel support issue 589832, Attempt to value-initialize pointer-to-member triggers internal error on Intel 11.1. Reported by John Maddock, 2010.
 | 
						|
 | 
						|
Note that all known GCC issues regarding value-initialization are fixed with GCC version 4.4, including
 | 
						|
[@http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 GCC Bug 30111]. Clang also has completely implemented
 | 
						|
value-initialization, as far as we know, now that [@http://llvm.org/bugs/show_bug.cgi?id=7139 Clang Bug 7139]
 | 
						|
is fixed.
 | 
						|
 | 
						|
New versions of __value_initialized__ (Boost release version 1.35 or higher) offer a workaround to these
 | 
						|
issues: __value_initialized__ may now clear its internal data, prior to constructing the object that it
 | 
						|
contains. It will do so for those compilers that need to have such a workaround, based on the
 | 
						|
[@boost:/doc/html/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_defects
 | 
						|
compiler defect macro] `BOOST_NO_COMPLETE_VALUE_INITIALIZATION`.
 | 
						|
 | 
						|
[#sec:types]
 | 
						|
[heading Types and objects]
 | 
						|
 | 
						|
[#sec:val_init]
 | 
						|
[heading `template class value_initialized<T>`]
 | 
						|
 | 
						|
```
 | 
						|
namespace boost {
 | 
						|
 | 
						|
template<class T>
 | 
						|
class __value_initialized__
 | 
						|
{
 | 
						|
 | 
						|
  public :
 | 
						|
 | 
						|
    __value_initialized__() : x() {}
 | 
						|
 | 
						|
    operator T const &() const { return x ; }
 | 
						|
 | 
						|
    operator T&() { return x ; }
 | 
						|
 | 
						|
    T const &data() const { return x ; }
 | 
						|
 | 
						|
    T& data() { return x ; }
 | 
						|
 | 
						|
    void swap( __value_initialized__& );
 | 
						|
 | 
						|
  private :
 | 
						|
 | 
						|
    [unspecified] x ;
 | 
						|
 | 
						|
} ;
 | 
						|
 | 
						|
template<class T>
 | 
						|
 | 
						|
T const& get ( __value_initialized__<T> const& x )
 | 
						|
{
 | 
						|
  return x.data();
 | 
						|
}
 | 
						|
 | 
						|
template<class T>
 | 
						|
T& get ( __value_initialized__<T>& x )
 | 
						|
{
 | 
						|
  return x.data();
 | 
						|
}
 | 
						|
 | 
						|
template<class T>
 | 
						|
void swap ( __value_initialized__<T>& lhs, __value_initialized__<T>& rhs )
 | 
						|
{
 | 
						|
  lhs.swap(rhs);
 | 
						|
}
 | 
						|
 | 
						|
} // namespace boost
 | 
						|
```
 | 
						|
 | 
						|
An object of this template class is a `T`-wrapper convertible to `'T&'` whose
 | 
						|
wrapped object (data member of type `T`) is [link sec:valueinit value-initialized] upon default-initialization
 | 
						|
of this wrapper class:
 | 
						|
 | 
						|
```
 | 
						|
int zero = 0;
 | 
						|
__value_initialized__<int> x;
 | 
						|
assert( x == zero ) ;
 | 
						|
 | 
						|
__std_string__ def;
 | 
						|
__value_initialized__< __std_string__ > y;
 | 
						|
assert( y == def ) ;
 | 
						|
```
 | 
						|
 | 
						|
The purpose of this wrapper is to provide a consistent syntax for value initialization
 | 
						|
of scalar, union and class types (POD and non-POD) since the correct syntax for value
 | 
						|
initialization varies (see [link sec:valueinitsyn value-initialization syntax]).
 | 
						|
 | 
						|
The wrapped object can be accessed either through the conversion operator
 | 
						|
`T&`, the member function `data()`, or the non-member function `get()`:
 | 
						|
 | 
						|
```
 | 
						|
void watch(int);
 | 
						|
 | 
						|
__value_initialized__<int> x;
 | 
						|
 | 
						|
watch(x) ; // operator T& used.
 | 
						|
watch(x.data());
 | 
						|
watch( get(x) ) // function get() used
 | 
						|
```
 | 
						|
 | 
						|
Both `const` and non-`const` objects can be wrapped. Mutable objects can be
 | 
						|
modified directly from within the wrapper but constant objects cannot:
 | 
						|
 | 
						|
When `T` is a __Swappable__ type, `__value_initialized__<T>`
 | 
						|
is swappable as well, by calling its `swap` member function
 | 
						|
as well as by calling `boost::swap`.
 | 
						|
 | 
						|
```
 | 
						|
__value_initialized__<int> x;
 | 
						|
static_cast<int&>(x) = 1 ; // OK
 | 
						|
get(x) = 1 ; // OK
 | 
						|
 | 
						|
__value_initialized__<int const> y ;
 | 
						|
static_cast<int&>(y) = 1 ; // ERROR: cannot cast to int&
 | 
						|
static_cast<int const&>(y) = 1 ; // ERROR: cannot modify a const value
 | 
						|
get(y) = 1 ; // ERROR: cannot modify a const value
 | 
						|
```
 | 
						|
 | 
						|
[warning
 | 
						|
 | 
						|
The __value_initialized__ implementation of Boost version 1.40.0 and older
 | 
						|
allowed ['non-const] access to the wrapped object, from a constant wrapper,
 | 
						|
both by its conversion operator and its `data()` member function.
 | 
						|
 | 
						|
For example:
 | 
						|
 | 
						|
```
 | 
						|
__value_initialized__<int> const x_c;
 | 
						|
int& xr = x_c ; // OK, conversion to int& available even though x_c is itself const.
 | 
						|
xr = 2 ;
 | 
						|
```
 | 
						|
 | 
						|
The reason for this obscure behavior was that some compilers did not accept the following valid code:
 | 
						|
 | 
						|
```
 | 
						|
struct X
 | 
						|
{
 | 
						|
  operator int&() ;
 | 
						|
    operator int const&() const ;
 | 
						|
  };
 | 
						|
  X x ;
 | 
						|
  (x == 1) ; // ERROR HERE!
 | 
						|
```
 | 
						|
 | 
						|
The current version of __value_initialized__ no longer has this obscure behavior.
 | 
						|
As compilers nowadays widely support overloading the conversion operator by having a `const`
 | 
						|
and a `non-const` version, we have decided to fix the issue accordingly. So the current version
 | 
						|
supports the idea of logical constness.
 | 
						|
 | 
						|
]
 | 
						|
 | 
						|
[h5 Recommended practice: The non-member get() idiom]
 | 
						|
 | 
						|
The obscure behavior of being able to modify a non-`const`
 | 
						|
wrapped object from within a constant wrapper (as was supported by previous
 | 
						|
versions of __value_initialized__) can be avoided if access to the wrapped object
 | 
						|
is always performed with the `get()` idiom:
 | 
						|
 | 
						|
```
 | 
						|
value_initialized<int> x;
 | 
						|
get(x) = 1; // OK
 | 
						|
value_initialized<int const> cx;
 | 
						|
get(x) = 1; // ERROR: Cannot modify a const object
 | 
						|
 | 
						|
value_initialized<int> const x_c;
 | 
						|
get(x_c) = 1; // ERROR: Cannot modify a const object
 | 
						|
 | 
						|
value_initialized<int const> const cx_c;
 | 
						|
get(cx_c) = 1; // ERROR: Cannot modify a const object
 | 
						|
```
 | 
						|
 | 
						|
[#sec:initialized]
 | 
						|
[heading `template class initialized<T>`]
 | 
						|
 | 
						|
 | 
						|
```
 | 
						|
namespace boost {
 | 
						|
 | 
						|
template<class T>
 | 
						|
class __initialized__
 | 
						|
{
 | 
						|
 | 
						|
  public :
 | 
						|
 | 
						|
    __initialized__() : x() {}
 | 
						|
 | 
						|
    explicit __initialized__(T const & arg) : x(arg) {}
 | 
						|
 | 
						|
    operator T const &() const;
 | 
						|
 | 
						|
    operator T&();
 | 
						|
 | 
						|
    T const &data() const;
 | 
						|
 | 
						|
    T& data();
 | 
						|
 | 
						|
    void swap( __initialized__& );
 | 
						|
 | 
						|
  private :
 | 
						|
 | 
						|
    [unspecified] x ;
 | 
						|
 | 
						|
};
 | 
						|
 | 
						|
template<class T>
 | 
						|
T const& get ( __initialized__<T> const& x );
 | 
						|
 | 
						|
template<class T>
 | 
						|
T& get ( __initialized__<T>& x );
 | 
						|
 | 
						|
template<class T>
 | 
						|
void swap ( __initialized__<T>& lhs, __initialized__<T>& rhs );
 | 
						|
 | 
						|
} // namespace boost
 | 
						|
```
 | 
						|
 | 
						|
The template class `boost::__initialized__<T>` supports both value-initialization
 | 
						|
and direct-initialization, so its interface is a superset of the interface
 | 
						|
of `__value_initialized__<T>`: Its default-constructor value-initializes the
 | 
						|
wrapped object just like the default-constructor of `__value_initialized__<T>`,
 | 
						|
but `boost::__initialized__<T>` also offers an extra `explicit`
 | 
						|
constructor, which direct-initializes the wrapped object by the specified value.
 | 
						|
 | 
						|
`__initialized__<T>` is especially useful when the wrapped
 | 
						|
object must be either value-initialized or direct-initialized, depending on
 | 
						|
runtime conditions. For example, `__initialized__<T>` could
 | 
						|
hold the value of a data member that may be value-initialized by some
 | 
						|
constructors, and direct-initialized by others.
 | 
						|
 | 
						|
On the other hand, if it is known beforehand that the
 | 
						|
object must ['always] be value-initialized, `__value_initialized__<T>`
 | 
						|
may be preferable. And if the object must always be
 | 
						|
direct-initialized, none of the two wrappers really needs to be used.
 | 
						|
 | 
						|
[#sec:initialized_value]
 | 
						|
[heading `initialized_value`]
 | 
						|
 | 
						|
```
 | 
						|
namespace boost {
 | 
						|
class __initialized_value_t__
 | 
						|
{
 | 
						|
  public :
 | 
						|
    template <class T> operator T() const ;
 | 
						|
};
 | 
						|
 | 
						|
__initialized_value_t__ const initialized_value = {} ;
 | 
						|
 | 
						|
} // namespace boost
 | 
						|
```
 | 
						|
 | 
						|
__initialized_value__ provides a convenient way to get
 | 
						|
an initialized value: its conversion operator provides an appropriate
 | 
						|
['value-initialized] object for any __CopyConstructible__ type.
 | 
						|
 | 
						|
Suppose you need to have an initialized variable of type `T`.
 | 
						|
You could do it as follows:
 | 
						|
 | 
						|
```
 | 
						|
T var = T();
 | 
						|
```
 | 
						|
 | 
						|
But as mentioned before, this form suffers from various compiler issues.
 | 
						|
The template __value_initialized__ offers a workaround:
 | 
						|
 | 
						|
```
 | 
						|
T var = get( __value_initialized__<T>() );
 | 
						|
```
 | 
						|
 | 
						|
Unfortunately both forms repeat the type name, which
 | 
						|
is rather short now (`T`), but could of course be
 | 
						|
more like `Namespace::Template<Arg>::Type`.
 | 
						|
 | 
						|
Instead, one could use __initialized_value__ as follows:
 | 
						|
 | 
						|
```
 | 
						|
T var = __initialized_value__;
 | 
						|
```
 | 
						|
 | 
						|
[#sec:references]
 | 
						|
[h5 References]
 | 
						|
 | 
						|
# Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote various papers,
 | 
						|
proposing to extend the support for brace-enclosed ['initializer lists]
 | 
						|
in C++. This [@https://en.cppreference.com/w/cpp/language/list_initialization feature] has
 | 
						|
now been available since C++11. This would allow a variable `var` of any __DefaultConstructible__ type
 | 
						|
`T` to be ['value-initialized] by doing `T var = {}`. The papers are listed at Bjarne's web page,
 | 
						|
[@http://www.research.att.com/~bs/WG21.html My C++ Standards committee papers].
 | 
						|
 | 
						|
# Scott Meyers, Effective C++, Third Edition, item 6, ['Explicitly disallow the use of
 | 
						|
compiler-generated functions you do not want], [@http://www.aristeia.com/books.html Scott Meyers: Books and CDs]
 | 
						|
 | 
						|
# The C++ Standard, Second edition (2003), ISO/IEC 14882:2003
 | 
						|
 | 
						|
# POD stands for "Plain Old Data"
 | 
						|
 | 
						|
[#sec:acknowledgements]
 | 
						|
[h5 Acknowledgements]
 | 
						|
 | 
						|
__value_initialized__ was developed by Fernando Cacciola, with help and suggestions
 | 
						|
from David Abrahams and Darin Adler.
 | 
						|
 | 
						|
Special thanks to Bjorn Karlsson who carefully edited and completed this documentation.
 | 
						|
 | 
						|
__value_initialized__ was reimplemented by Fernando Cacciola and Niels Dekker
 | 
						|
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
 | 
						|
 | 
						|
`boost::__initialized__` was very much inspired by feedback from Edward Diener and Jeffrey Hellrung.
 | 
						|
 | 
						|
__initialized_value__ was written by Niels Dekker, and added to Boost release version 1.36 (2008).
 | 
						|
 | 
						|
Developed by [@mailto:fernando_cacciola@hotmail.com Fernando Cacciola]. The latest version of
 | 
						|
this file can be found at [@http://www.boost.org www.boost.org].
 | 
						|
 | 
						|
[endsect]
 |