6

考虑到

struct C { 
   C()            { printf("C::C()\n"          ); }
   C(int)         { printf("C::C(int)\n"       ); }
   C( const C& )  { printf("copy-constructed\n"); }
};

和一个模板函数

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  >();
}

看着t1,它不会在Tis eg时被初始化int。另一方面,t2将从默认构造的临时复制构造。

问题:除了 template-fu 之外,C++ 中是否可以默认构造一个泛型变量?

4

4 回答 4

5

这是您可以使用的技巧,使用本地类:

template <typename T> void foo() {
    struct THolder {
        T obj;
        THolder() : obj() { } // value-initialize obj
    };

    THolder t1; // t1.obj is value-initialized
}

我想我从另一个 Stack Overflow 问题的答案中读到了这个技巧,但目前我找不到那个问题。

或者,您可以使用boost::value_initialized<T>类模板,它基本上做同样的事情,具有更大的灵活性和一致性,并为有缺陷的编译器提供了解决方法。

在 C++0x 中,这要容易得多:您可以使用一个空的初始化列表:

T obj{}; // obj is value-initialized

(据我所知,只有 gcc 4.5+ 支持 C++0x 初始化列表。Clang 和 Visual C++ 还不支持它们。)

于 2011-03-14T18:55:31.130 回答
2

如果您不关心复制构造函数必须存在的事实,并且只想阻止它被调用:

别担心:不会的。在这种情况下,复制构造函数调用被省略。始终可靠——即使您在禁用优化的情况下进行编译( -O0)。

于 2011-03-14T19:05:47.633 回答
0

你真正的问题是什么?为t1实例调用默认构造函数。

于 2011-03-14T18:56:12.587 回答
0

T t2 = T(); // 将调用默认构造函数,然后复制构造函数... :(

不在我的编译器(VC2008)上。对我来说输出是...

C::C()
C::C()

这是我期望它做的。我错过了什么吗?

于 2011-03-14T19:00:12.203 回答