有条件地构造参数包的默认可构造类

Conditionally construct default-constructible classes of a parameter pack

本文关键字:默认 参数 有条件      更新时间:2023-10-16

我有一个模板类Container,其中模板构造函数定义如下:

template<class... Objects>
class Container
{
public:
    template<class... Objs>
    Container(Objs*... objs)
    {
        // initialize all pointers of m_objs to nullptr
        objs_init<Objects...>();
        // initialize the pointers of m_objs corresponding to parameters pack objs...
        objs_init<Objs...>(objs...);
    }
private:
    template<class Obj, class O1, class ...On>
    void objs_init()
    {
        objs_init<Obj>();
        objs_init<O1, On...>();
    }
    template<class Obj, class O1, class ...On>
    void objs_init(Obj* obj, O1* o1, On*... on)
    {
        objs_init<Obj>(obj);
        objs_init<O1, On...>(o1, on...);
    }
    template<class Obj>
    void objs_init(Obj* obj = nullptr)
    {
        std::get<Obj*>(m_objs) = obj;
    }
    std::tuple<Objects*...>     m_objs;
};

和一些类ABC,...定义如下:

class A { public: A(bool) {} };
class B { /*trivial default ctor*/ };
class C { public: C(int) {} };

如果我以这种方式创建一个Container<A,B,C>对象:

    Container<A,B,C> cnt(new A(true), new C(1));

假设模板参数中指定的所有类都不同,则Container<>模板构造函数按预期工作,即:

  • m_objs元组的所有指针首先设置为 nullptr,然后
  • m_objs的第一个(A*(和第三个(C*(指针分别设置为new A(true)new C(1)返回的值。

现在,我希望Container<>构造函数默认构造m_objs的每个未初始化的指针。但我不知道如何实现这一目标。

我尝试将以下模板成员函数添加到Container<>

    template<class Obj, class O1, class ...On>
    void objs_ctor()
    {
        objs_ctor<Obj>();
        objs_ctor<O1, On...>();
    }
    template<class Obj>
    void objs_ctor()
    {
        Obj*& obj = std::get<Obj*>(m_objs);
        if (obj == nullptr)
            obj = new Obj;
    }

以及在构造函数Container<>调用objs_ctor<>

        // default-construct unitialized pointers of `m_objs`
        objs_ctor<Objects...>();            

但是,这显然不起作用,因为我实现objs_ctor<>的方式要求参数包的每个类都存在默认构造函数(我不想这样做(;所以我收到以下编译器错误:

error C2512: 'A' : no appropriate default constructor available

为了使其正常工作,我还需要检查我尝试自动创建的对象是否是默认可构造的。我认为这可以使用std::is_default_constructible<>来实现,但我不知道如何正确使用它。

感谢您的帮助。

假设。

在构造函数中添加对objs_ctors<Objects...>();的调用

  template<class... Objs>
     Container(Objs*... objs)
      {
        objs_init<Objects...>();
        objs_init<Objs...>(objs...);
        objs_ctors<Objects...>();
      }

并以这种方式定义objs_ctor<>()objs_ctors<>()

  template <typename Obj>
     typename std::enable_if<true == std::is_default_constructible<Obj>::value, void>::type objs_ctor ()
      {
        Obj * & obj = std::get<Obj*>(m_objs);
        if ( obj == nullptr)
           obj = new Obj;
      }
  template <typename Obj>
     typename std::enable_if<false == std::is_default_constructible<Obj>::value, void>::type objs_ctor ()
      { }
  template <typename Obj, typename O1, typename ... On>
     void objs_ctors()
      {
        objs_ctor<Obj>();
        objs_ctors<O1, On...>();
      }
  template <typename Obj>
     void objs_ctors ()
      {
        objs_ctor<Obj>();
      }

请注意:我想你的例子

    Obj*& obj = std::get<Obj*>(m_objs);
    if (obj != nullptr)
        obj = new Obj;

错了。

我想你的意图是修改(分配(objobjnullptr时,所以

    Obj*& obj = std::get<Obj*>(m_objs);
    if (obj == nullptr)
        obj = new Obj;

PS:对不起,我的英语不好。