Если это ваш шаблон класса:
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
};
Тогда любая (неявный) специализация имеет только конструктор по умолчанию. Вы можете
Добавить нестандартную CT к (первичному) шаблону
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() { /* ... */ }
частично или явно специализировать шаблон класса
template <> class t_simple_db<std::string, double>{
/* ... */
t_simple_db(std::string, std::size_t n) { /*...*/ }
~t_simple_db(){}
//many methods
};
Для того, чтобы определить CTOR вне определения класса: Явный (= полностью) специализированные шаблоны классов являются «обычные» классы, не шаблонов (Вы не можете создавать типы из них, они являются типов с странные имена). Поэтому обычные правила для функций + УСО применяются: предпочтительно поместить их в исходный файл (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, есть т е р
t_simple_db(const string& keys, const size_t& res);
Я не рекомендовал бы поставить этот CTOR в основном шаблоне: не все специализации t_simple_db
могут использовать string
с, как Tkey
с. Вы можете использовать наследование для предоставления дополнительного 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)
{
/*...*/
}
Причина, почему эта функция должна быть в исходном файле, что это не шаблон. I.e., это не проект, который компилятор использует для , делает функции, но это полная функция. Следовательно, он должен следовать правилу Единого определения. В отличие от шаблонов и членов шаблонов классов, компоновщик не объединяет определения. Вы также можете указать определение внутри определения класса, неявно делая функцию 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)
{
/*...*/
}
Эта функция не шаблон либо, так что одни и те же правила, что и для функции члена явной специализации/как и для обычных функций.
Можете ли вы показать нам, что вы пробовали до сих пор? – dyp
Если у вас есть C++ 11, вы можете использовать для него вариационный шаблон, поэтому класс ... Args как параметр шаблона. – CashCow
@dyp НЕ принимайте случайный пример как вопрос. Это можно сделать несколькими путями. Дело в том, как написать конструктор, который возвращает специализированный объект. – DarioP