【问题标题】:How do I stop this templated function value-initializing a new constructed object?如何停止这个模板化函数值初始化一个新的构造对象?
【发布时间】:2021-04-08 04:35:19
【问题描述】:

如果我可以在创建新对象时为构造函数参数提供参数包,并且我不提供任何构造函数参数,那么结果将是:new T();如果它没有用户提供的构造函数,它将对对象进行值初始化。我该如何阻止这种情况发生?

template <typename T>
struct Foo
{
    template <typename ... ConstructorArgs>
    static void create(ConstructorArgs ... constructorArgs)
    {
        T* ptr = new T(constructorArgs ...);
        T* ptr2 = new T;
        std::cout << *ptr; // It seems it value-initialized (zero-initialized) it
        std::cout << *ptr2; // Default initialized it

    }

};
int main()
{
    Foo<int>::create();
}

【问题讨论】:

  • 你不能。如果目标是在不初始化对象的情况下进行内存分配,则必须使用placement new。
  • @super Placement new 仍然导致 value-init, char buf[4];新的 (buf) T(constructorArgs...);仍然 value_initialized 它为 0。
  • 是的,关键是它把分配和初始化分成了两个步骤。所以就像我上面说的...... 如果目标是在不初始化对象的情况下进行内存分配
  • 另外,这里的模板部分与问题有什么关系?
  • @super 如果我有一个普通的 struct PlainStruct { int a, char b; };我没有向 Foo::create(); 传递任何参数它会对它进行值初始化,这意味着对成员“a”和“b”进行零初始化。我发布了一个答案,它适用于 sizeof 参数包。

标签: c++ parameter-pack value-initialization


【解决方案1】:

这适用于 constexpr sizeof... (ConstructorArgs),但我也想知道是否有更好的方法。

template <typename T>
struct Foo
{
    template <typename ... ConstructorArgs>
    static void create(ConstructorArgs ... constructorArgs)
    {
        T* ptr;
        if constexpr (sizeof ... (ConstructorArgs) == 0)
            ptr = new T;
        else
            ptr = new T(constructorArgs ...);
    }

};
int main()
{
    Foo<int>::create(); // Default initializes
    Foo<int>::create(0); // Value/Zero initialized

}

它适用于 new 和放置 new,以及左值堆栈变量,但不是临时的,即 T{ },因为如果 T 没有用户定义的构造函数,这些大括号将值初始化。

【讨论】:

  • 我认为没有更好的方法。
猜你喜欢
  • 1970-01-01
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-15
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
相关资源
最近更新 更多