我正在编写一个模板类,我的代码中的某一点希望能够在堆栈上对参数化类型的对象进行值初始化。现在,我正在通过写一些这样的效果来实现这个目标:
template <typename T> void MyClass<T>::doSomething() {
T valueInitialized = T();
/* ... */
}
此代码有效,但(除非编译器是智能的)它需要不必要的创建和销毁临时T
对象。我想写的是以下内容,我知道这是不正确的:
template <typename T> void MyClass<T>::doSomething() {
T valueInitialized(); // WRONG: This is a prototype!
/* ... */
}
我的问题是,是否有一种很好的方法来初始化自动对象,而不必显式构造临时对象并将其分配给自动对象。可以这样做吗?或者T var = T();
和它一样好吗?
答案 0 :(得分:23)
以下使用复制初始化,在C ++ 03中95%的时间“可能很好”:
T var = T();
但对于泛型 C ++ 03代码,您应该始终更喜欢 direct-initialization 来解释其他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.
或者更好的是,使用Boost。Utility.ValueInit库,它为您打包理想的行为以及各种编译器缺陷的解决方法(遗憾的是,不止一个人会想到):
boost::value_initialized<T> var;
对于C ++ 11,可以使用列表初始化语法以极低噪声/丑陋的方式实现直接值初始化:
T var{}; // unambiguously value-initialization*
(* Nb这只是没有一元构造函数取一些std::initializer_list<>
的类型的值初始化;对于那样做的类型,将调用该构造函数 - “统一初始化”确实...当然,对于理智的类型,净结果应该是相同的。)
答案 1 :(得分:16)
您可以在C ++ 0x中使用花括号:
T valueInitialized{};
答案 2 :(得分:5)
不,没有任何其他方法可以在C ++ 03中可靠地初始化模板类型。
如果你可以指望T
只是具有默认构造函数的类类型,你可以写
T valueInitialized;
但如果T
也可能是内置类型,
T valueInitialized = T();
是要走的路。
您是否有理由不相信您的编译器优化该副本?