模板类的专门构造函数

达里奥

我想向模板类添加一个构造函数,该构造函数通过一些初始化来构建专用对象。这是我正在从事的课程:

template <typename Tkey, typename Tdata> class t_simple_db{
 private:
  typedef typename std::list<std::pair<Tkey,vector<Tdata>>> t_internal;
  t_internal _db;

 public:
  typedef typename t_internal::const_iterator const_iterator;
  typedef typename t_internal::iterator iterator;

  t_simple_db(){;}
  ~t_simple_db(){;}

  //many methods
};

现在我想

typedef t_simple_db<string,double> t_simple_db_sd;

并为此编写一个特殊的构造函数,以便在主体中我可以简单地调用如下代码:

t_simple_db_sd db("this is a string", 100u);

具有正确的实例化和初始化的对象。我试图将其放置在类声明之后的标题中:

typedef t_simple_db<string, double> t_simple_db_sd;
template<> t_simple_db<string, double>::t_simple_db(...) {
  ...
}

但是当我尝试编译时会遇到很多错误。

如果这是您的课程模板:

template <typename Tkey, typename Tdata> class t_simple_db{
 private:
  typedef typename std::list<std::pair<Tkey,vector<Tdata>>> t_internal;
  t_internal _db;

 public:
  typedef typename t_internal::const_iterator const_iterator;
  typedef typename t_internal::iterator iterator;

  t_simple_db(){;}
  ~t_simple_db(){;}

  //many methods
};

然后,任何(隐式)专门化都只有一个默认构造函数。你可以

  1. 将非默认ctor添加到(主)类模板

    template <typename Tkey, typename Tdata> class t_simple_db{
      /* ... */
    
      t_simple_db(){;}
      t_simple_db(Tkey, std::size_t n) { /*...*/ }
      ~t_simple_db(){;}
    
      //many methods
    };
    

    为了在类定义之外定义ctor,将其放在头文件中

    template <typename Tkey, typename Tdata>
    t_simple_db::t_simple_db() { /* ... */ }
    
  2. 部分或明确地专门化类模板

    template <> class t_simple_db<std::string, double>{
      /* ... */
      t_simple_db(std::string, std::size_t n) { /*...*/ }
      ~t_simple_db(){}
    
      //many methods
    };
    

    为了在类定义之外定义ctor:显式(=完全)专门的类模板是“普通”类,而不是模板(您不能从它们创建类型,它们具有奇怪名称的类型)。因此,适用于函数+ ODR的通常规则:最好将其放入源文件(cpp)中,或者作为inline头文件中的内部链接

    // no `template`
    t_simple_db<std::string, double>::t_simple_db(..) { /*...*/ }
    
    // or
    typedef t_simple_db<string, double> t_simple_db_sd;
    t_simple_db_sd::t_simple_db(..) { /*...*/ }
    

在您的pastebin中,有一个ctor

t_simple_db(const string& keys, const size_t& res );

我不建议将此ctor放在主模板中:并非所有的专业化都t_simple_db可能将strings用作Tkeys。您可以使用继承仅为某些专业提供额外的ctor,例如

// header file

template <typename Tkey, typename Tdata> class t_simple_db_base{
 public:
  t_simple_db_base(){;}
  ~t_simple_db_base(){;} // possibly virtual

  //many methods
};

template <typename Tkey, typename Tdata>
class t_simple_db : public t_simple_db_base<Tkey, Tdata>{
 public:
  t_simple_db(){;}
  ~t_simple_db(){;}
};

// explicit specialization of `t_simple_db`
template <>
class t_simple_db<std::string, double>
    : public t_simple_db_base<std::string, double>{
 public:
  t_simple_db(){;}
  t_simple_db(const string& keys, const size_t& res);
  ~t_simple_db(){;}
};

typedef t_simple_db<std::string, double> t_simple_db_sd;


// source file

//template <>  <-- not a member function of a class template,
//                 but of an "ordinary class"
t_simple_db_sd::t_simple_db(const string& keys, const size_t& res)
{
    /*...*/
}

此功能必须在源文件中的原因是它不是模板也就是说,这不是编译器用来制作函数的蓝图,而是它本身是一个完整的函数。因此,它需要遵循一个定义规则。与模板和类模板的成员相反,链接器不会合并定义。您还可以在类定义中提供定义,以隐式地创建函数inline如果将函数显式标记为,也可以在类定义之外的头文件中提供该定义inline如果该功能为inline,则它可能会以多个翻译单位出现。

也可以为所有专业声明ctor,但仅为定义它t_simple_db<std::string, double>我不推荐这种方法,因为将ctor误用于其他专业领域只会导致链接器错误。不过,您可以按照以下方式进行操作:

// header file

template <typename Tkey, typename Tdata> class t_simple_db{
 public:
  t_simple_db(){;}
  t_simple_db(const string& keys, const size_t& res );
  ~t_simple_db(){;}

  //many methods
};

typedef t_simple_db<std::string, double> t_simple_db_sd;


// source file
template <>   // <-- this is a member function of a class template,
              //     therefore we need the `template <>`
              //     in this example, t_simple_db_sd is *not* an explicit
              //     specialization
t_simple_db_sd::t_simple_db(const string& keys, const size_t& res)
{
    /*...*/
}

此函数也不是模板,因此适用于明确专门化成员函数的规则/适用于普通函数的规则。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

具有模板构造函数专门化的模板类,用于初始化模板化的基类

来自分类Dev

模板类-成员函数专门化

来自分类Dev

模板类-成员函数专门化

来自分类Dev

模板构造器中的模板类专门化

来自分类Dev

模板构造器中的模板类专门化

来自分类Dev

使用部分模板类作为专门的模板函数

来自分类Dev

复制模板类的构造函数

来自分类Dev

专攻模板类构造函数

来自分类Dev

专攻模板类构造函数

来自分类Dev

模板类的复制构造函数

来自分类Dev

条件类模板构造函数

来自分类Dev

从类模板继承模板构造函数?

来自分类Dev

从模板基类的模板构造函数派生

来自分类Dev

类any中的模板构造函数与非模板构造函数

来自分类Dev

类any中的模板构造函数与非模板构造函数

来自分类Dev

如何专门化模板类成员函数?

来自分类Dev

专门化模板派生类的成员函数

来自分类Dev

C ++-部分专门化模板类成员函数

来自分类Dev

类模板特殊成员函数显式专门化

来自分类Dev

使用当前类专门化继承的模板化函数

来自分类Dev

C ++-专门化类模板的成员函数

来自分类Dev

根据类模板参数敲除类模板构造函数

来自分类Dev

从模板派生类调用模板基类的构造函数

来自分类Dev

模板类找不到构造函数

来自分类Dev

模板类构造函数的专业化

来自分类Dev

模板类复制构造函数未调用

来自分类Dev

模板类和遍历的默认构造函数

来自分类Dev

在构造函数中使用模板类

来自分类Dev

如何从类构造函数传递模板参数