Reputation: 13
I seem to have a hard time describing my problem, so I was unsuccessful searching for previous answers.
I have the next code written in c++17 - It has Data class which can hold a templated argument (and size_t as id). Next I have a DataBase class that holds a tuple of Data instances. Than in main, I have an example for a DataBase instance with different Data types, but the user maliciously inserted into the database a non-Data class variable. I need to prevent it.
// 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
}
The code attempts to make my question clear. I want to make class database accept Data instances with different template arguments (as seen in main func), but not accept any other type of data.
If I am generalizing my template line as <class... DATA_TYPES>, maybe I can use some static assert or "constexpr if" in the ctor, but there should be a way to change the template line to accept only Data class type with variadic different types (and size_t as ID) template..
Help will be appreciated!
Upvotes: 1
Views: 38
Reputation: 12928
You need a way to determine if a type is an instatiation of Data
. One way is to use partial template specialization on a template variable.
Once we have that we throw in a static_assert
in 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
}
Upvotes: 1