简体   繁体   English

模板函数:在C ++中没有复制构造的默认构造

[英]Template functions: default construction without copy-constructing in C++

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 eg int . 查看t1 ,当T为例如int时,它不会被初始化。 On the other hand, t2 will be copy-constructed from a default constructed temporary. 另一方面, t2将从默认构造的临时复制构造。

The question: is it possible in C++ to default-construct a generic variable, other than with template-fu? 问题是:在C ++中是否可以默认构造一个通用变量,而不是使用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. 我想我从另一个Stack Overflow问题的答案中读到了这个技巧,但我现在无法找到这个问题。

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. 或者,您可以使用boost::value_initialized<T>类模板,它基本上做同样的事情,具有更大的灵活性和一致性,并为错误的编译器提供了变通方法。

In C++0x, it's much easier: you can use an empty initializer list: 在C ++ 0x中,它更容易:您可以使用空的初始化列表:

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.) (据我所知,只有gcc 4.5+支持C ++ 0x初始化列表.Clang和Visual C ++还不支持它们。)

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 ). 始终,可靠 - 即使在禁用优化-O0 )的情况下编译也是如此

What is your real question? 你真正的问题是什么? The default constructor is called for t1 instance. t1实例调用默认构造函数。

T t2 = T(); T t2 = T(); // will call default constructor, then copy constructor... :( //将调用默认构造函数,然后复制构造函数...... :(

Not on my compiler (VC2008). 不在我的编译器(VC2008)上。 Output for me is... 我的输出是......

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

Which is what I'd expect it to do. 这是我期望它做的。 Am I missing something? 我错过了什么吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM