【问题标题】:How can I initialize a variable of template type in a default constructor如何在默认构造函数中初始化模板类型的变量
【发布时间】:2019-11-18 04:59:55
【问题描述】:

我正在创建一个 Node 结构,并希望创建一个初始化每个成员变量的默认构造函数。

struct Node {
    Node* next;
    Node* prev;
    T datum;

    Node()
    { 
        next = nullptr; 
        prev = nullptr;
        datum = ??????
    }
};

既然 datum 是 T 类型,它是一个模板类型,我可以在这里设置 datum 等于什么?将其设置为 NULL 会给我一个编译器错误。

编辑:澄清一下,我想初始化变量,以便稍后在我的代码中修改它们。

【问题讨论】:

  • 应该设置为等于什么? T 是整数类型有关系吗?字符串类型?您从未见过的课程?
  • 从技术上讲,您正在稍后在代码中修改datum,因为它在您的(空)member initializer list 中初始化,然后由正文中的赋值语句修改你的构造函数。

标签: c++ templates constructor


【解决方案1】:

我想通了!如果你把默认构造函数写成

Node(){}

初始化将被自动处理。

【讨论】:

  • 这是不正确的。通过该实现,不能保证 nextprev 将被初始化为 nullptr
【解决方案2】:

你能做的最好的就是:

Node() : next(nullptr), prev(nullptr), datum()
{ 
}

请注意,如果T 不是默认可构造的,它将失败。

【讨论】:

    【解决方案3】:

    我愿意:

    struct Node {
        Node* next = nullptr;
        Node* prev = nullptr;
        T datum{};
    
        Node() = default;
    };
    

    【讨论】:

      【解决方案4】:

      如果T 是某个类并且声明了默认构造函数,那么您根本不需要做任何事情。默认情况下,该成员将被初始化。

      如果你需要调用特定的构造函数,有很多可能性:

      • 首先,您可以在成员声明中设置初始化程序。 IE。 T datum { };T datum { 1 /*, other args*/ };。就是这样;
      • 其次,您可以在构造函数中提供初始化。喜欢Node() : datum { /*blah-blah */ } { /* the body */ }。只是不要忘记初始化nextprev
      • 第三,你可以使用T,就像它的类型一样。 IE。您可以在构造函数中编写 datum = T(/* args go here */);datum = T { /* yeah, here too */ }; 之类的内容。但是需要注意的是:这不是初始化,而是初始化后的赋值。初始化将通过前两个选项完成;

      一个完整的例子:

      struct Node {
          Node* next;
          Node* prev;
          T datum { 0 }; // for all constructors
      
          Node() : datum { 1 } // for this particular constructor
          { 
              next = nullptr; 
              prev = nullptr;
              datum = { 2 }; // assign new value now
          }
      };
      

      不确定您是否需要以下内容,但以防万一(和后代:))。

      如果要用作T 的类没有可行的构造函数,或者它们有不同的参数,或者有其他原因阻止您对它们都使用一个初始化器...

      您可以强制这些类具有像 default_value 这样的静态字段和复制构造函数。然后你可以像这样初始化:T datum = T::default_value;。静态字段可以替换为变量模板。

      或者,如果您真的需要,您可以定义类似代理的东西。现在我们有了复制省略,您可以定义为您提供所需值的函数模​​板。

      看起来像这样:

      template <typename T>
      T default_value() { return { /* very default arguments */ }; }
      // or if you don't need that very default body:
      // T default_value();
      template <>
      A default_value<A>() { return { /* A constructor arguments */ }; }
      template <>
      B default_value<B>() { return { /* B constructor arguments */ }; }
      

      所以在Node 中你可以声明像T datum = default_value&lt;T&gt;(); 这样的成员。在 C++17 中,它不需要类具有复制构造函数或其他东西,当您已经知道特定的类时,您只需在 default_value 函数的 return 语句中以某种方式构造它。所以不需要修改类。是的,该函数可以有参数,您可以在 Node() 构造函数中提供这些参数;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多