You could define a std::tuple
based type to describe the accepted types and then use SFINAE to enable instantiating a class from the template based on that.
Example (replace with your own types as needed):
#include <tuple>
#if defined(VARIANT1)
using accepted_types = std::tuple <std::string, std::set<int>>;
#elif defined(VARIANT2)
using accepted_types = std::tuple <std::map<int,int>, std::vector<int>>;
#endif
Then we need a has_type
type trait to check if one type is included in a std::tuple
based type (see link to that answer for the full description):
#include <type_traits>
template <typename T, typename Tuple>
struct has_type;
template <typename T>
struct has_type<T, std::tuple<>> : std::false_type {};
template <typename T, typename U, typename... Ts>
struct has_type<T, std::tuple<U, Ts...>> : has_type<T, std::tuple<Ts...>> {};
template <typename T, typename... Ts>
struct has_type<T, std::tuple<T, Ts...>> : std::true_type {};
template<class T, class V>
static constexpr bool has_type_v = has_type<T, V>::value;
Then enable the template only for those types included in accepted_types
:
template <typename VarType,
typename = std::enable_if_t<has_type_v<VarType, accepted_types>>>
class CMyClass {
};
Demo