gpt4 book ai didi

c++ - 模板类的专用构造函数

转载 作者:太空宇宙 更新时间:2023-11-04 11:41:24 25 4
gpt4 key购买 nike

我想向模板类添加一个构造函数,该构造函数通过一些初始化来构建专用对象。这是我正在学习的类(class):

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. 将非默认构造函数添加到(主要)类模板

    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
    };

    为了在类定义之外定义构造函数:显式(=完全)专用类模板是“普通”类,而不是模板(您不能从它们,它们具有奇怪名称的类型)。因此,适用函数 + 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 的所有特化可能会使用 string作为 Tkey秒。您可以使用继承来仅为某些特化提供额外的构造函数,例如

// 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 , 它可能出现在多个翻译单元中。

也可以为所有特化声明构造函数,但只为 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)
{
/*...*/
}

此函数也不是模板,因此适用于显式特化的成员函数/普通函数的相同规则。

关于c++ - 模板类的专用构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21264530/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com