Considering
struct C {
C() { printf("C::C()\n" ); }
C(int) { printf("C::C(int)\n" ); }
C( const C& ) { printf("copy-constructed\n"); }
};
And a template function
template< typename T > void foo(){
// default-construct a temporary variable of type T
// this is what the question is about.
T t1; // will be uninitialized for e.g. int, float, ...
T t2 = T(); // will call default constructor, then copy constructor... :(
T t3(); // deception: this is a local function declaration :(
}
int main(){
foo<int>();
foo<C >();
}
Looking at t1
, it will not be initialized when T
is e.g. int
. On the other hand, t2
will be copy-constructed from a default constructed temporary.
The question: is it possible in C++ to default-construct a generic variable, other than with template-fu?
Here's a trick you can use, using a local class:
template <typename T> void foo() {
struct THolder {
T obj;
THolder() : obj() { } // value-initialize obj
};
THolder t1; // t1.obj is value-initialized
}
I think I read about this trick from an answer to another Stack Overflow question, but I am unable to find that question at the moment.
Alternatively, you can use the boost::value_initialized<T>
class template, which basically does the same thing, with greater flexibility and consistency and with workarounds for buggy compilers.
In C++0x, it's much easier: you can use an empty initializer list:
T obj{}; // obj is value-initialized
(To the best of my knowledge, only gcc 4.5+ supports C++0x initializer lists. Clang and Visual C++ don't yet support them.)
If you don’t care for the fact that the copy constructor must exist, and just want to prevent it being called:
Don’t worry: it won’t be. The copy constructor call will be elided in this situation. Always, and reliably – even when you compile with optimizations disabled (-O0
).
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