首页 > 解决方案 > 以模板类为参数的可变参数类构造函数

问题描述

我似乎很难描述我的问题,所以我没有成功寻找以前的答案。

我有下一个用 c++17 编写的代码——它有 Data 类,它可以保存一个模板化的参数(和 size_t 作为 id)。接下来,我有一个包含 Data 实例元组的 DataBase 类。与主要相比,我有一个具有不同数据类型的 DataBase 实例的示例,但用户恶意地将一个非 Data 类变量插入到数据库中。我需要阻止它。

// a data to be in the database
template <size_t ID, class T>
class Data
{
   public:
    Data(T var) : m_var(var) {}

    size_t id = ID;
    T m_var;
};

//Here is the database. How should I only accept Data class with different template type... 
template <class... DATA_TYPES>
class DataBase
{
  public:
    DataBase(DATA_TYPES... args) : m_data(args...) {}
    std::tuple<DATA_TYPES...> m_data;
};



int main() {
 
    DataBase d(Data<0, int>(10),
               Data<1, char>(40),
                "an invalid member"); //<------- should not be able to compile  
}

该代码试图使我的问题清楚。我想让类数据库接受具有不同模板参数的 Data 实例(如 main func 中所示),但不接受任何其他类型的数据。

如果我将我的模板行概括为 <class...DATA_TYPES>,也许我可以在 ctor 中使用一些静态断言或“constexpr if”,但应该有一种方法可以将模板行更改为仅接受 Data 类类型可变参数不同类型(和 size_t 作为 ID)模板..

帮助将不胜感激!

标签: templatesc++17

解决方案


您需要一种方法来确定一个类型是否是Data. 一种方法是对模板变量使用部分模板特化。

一旦我们有了它,我们就会投入一个static_assertin Database

#include <tuple>

// a data to be in the database
template <std::size_t ID, class T>
class Data
{
   public:
    Data(T var) : m_var(var) {}

    std::size_t id = ID;
    T m_var;
};

template <typename T>
constexpr bool isData = false;

template <std::size_t ID, typename T>
constexpr bool isData<Data<ID, T>> = true;

//Here is the database. How should I only accept Data class with different template type... 
template <class... DATA_TYPES>
class DataBase
{
    static_assert((isData<DATA_TYPES> && ...));
  public:
    DataBase(DATA_TYPES... args) : m_data(args...) {}
    std::tuple<DATA_TYPES...> m_data;
};



int main() {
    DataBase d(Data<0, int>(10),
               Data<1, char>(40),
                "an invalid member"); //<------- should not be able to compile  
}

推荐阅读