模板函数:C++ 中默认构造,无需复制构造;

发布于 2024-10-21 15:10:19 字数 832 浏览 4 评论 0原文

考虑

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,当T为例如int时,它不会被初始化。另一方面,t2 将从默认构造的临时复制构造

问题:除了使用 template-fu 之外,在 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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

难理解 2024-10-28 15:10:19

这是一个你可以使用的技巧,使用本地类:

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 类模板,它基本上执行相同的操作,具有更大的灵活性和一致性,并针对有缺陷的编译器提供了解决方法。

在 C++0x 中,这要容易得多:您可以使用空的初始值设定项列表:(

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

据我所知,只有 gcc 4.5+ 支持 C++0x 初始值设定项列表。Clang 和 Visual C++ 尚不支持它们。)

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.)

硬不硬你别怂 2024-10-28 15:10:19

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

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

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).

找回味觉 2024-10-28 15:10:19

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

What is your real question? The default constructor is called for t1 instance.

娜些时光,永不杰束 2024-10-28 15:10:19

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

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

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

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

T t2 = T(); // will call default constructor, then copy constructor... :(

Not on my compiler (VC2008). Output for me is...

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

Which is what I'd expect it to do. Am I missing something?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文