使用没有模板参数的类型作为模板参数
Using a type without template arguments as a template argument
我有一个名为 Registry
的 class,它将 ID 与一些数据相关联。
我想这样做,以便存储这些对的底层结构可以是任何 std::map
ish 类型,用户可以定义(例如:std::map
、std::unordered_map
)。
我最初的想法是做这样的事情:
template<typename Value, typename Container, typename ID = size_t>
class Registry{
using Storage = Container<ID, value>;
static_assert(std::is_same<Storage, std::map> || std::is_same<Storage, std::map>, "Underlying storage type must be a std::map-ish.");
public:
Storage<ID, Value> store;
...
但是,尝试使用 class 会导致错误:
Registry<bool, std::map> testRegistry;
err) argument list for class template std::map is missing
我理解编译器的抱怨,但是有什么方法可以解决这个问题,以便这种语法(或类似的语法)可以工作吗?
感谢您的建议。
您需要将 Container
声明为 template template parameter。例如
template<typename Value, template <typename...> class Container, typename ID = size_t>
class Registry{
using Storage = Container<ID, Value>;
static_assert(std::is_same_v<Storage, std::map<ID, Value>> || std::is_same_v<Storage, std::unordered_map<ID, Value>>, "Underlying storage type must be a std::map-ish.");
public:
Storage store;
...
其他问题:
Storage
是一个实例化,所以不要为它指定模板参数。
- 为
std::map
指定模板参数。
- 作为
static_assert
的条件你应该使用std::is_same_v
(或者std::is_same<...>::value
代替。
作为替代方案,您可以只提供容器,而不是键、值和模板容器:
template <typename Container>
class Registry
{
using ID = typename Container::key_type;
using Value = typename Container::mapped_type;
static_assert(std::is_same_v<Container, std::map<ID, Value>>
|| std::is_same_v<Container, std::unordered_map<ID, Value>>,
"Underlying storage type must be a std::map-ish.");
// ...
};
随着使用
Registry<std::map<std::size_t, bool>> testRegistry;
Registry<std::unordered_map<std::size_t, float>> testRegistry2;
我有一个名为 Registry
的 class,它将 ID 与一些数据相关联。
我想这样做,以便存储这些对的底层结构可以是任何 std::map
ish 类型,用户可以定义(例如:std::map
、std::unordered_map
)。
我最初的想法是做这样的事情:
template<typename Value, typename Container, typename ID = size_t>
class Registry{
using Storage = Container<ID, value>;
static_assert(std::is_same<Storage, std::map> || std::is_same<Storage, std::map>, "Underlying storage type must be a std::map-ish.");
public:
Storage<ID, Value> store;
...
但是,尝试使用 class 会导致错误:
Registry<bool, std::map> testRegistry;
err) argument list for class template std::map is missing
我理解编译器的抱怨,但是有什么方法可以解决这个问题,以便这种语法(或类似的语法)可以工作吗?
感谢您的建议。
您需要将 Container
声明为 template template parameter。例如
template<typename Value, template <typename...> class Container, typename ID = size_t>
class Registry{
using Storage = Container<ID, Value>;
static_assert(std::is_same_v<Storage, std::map<ID, Value>> || std::is_same_v<Storage, std::unordered_map<ID, Value>>, "Underlying storage type must be a std::map-ish.");
public:
Storage store;
...
其他问题:
Storage
是一个实例化,所以不要为它指定模板参数。- 为
std::map
指定模板参数。 - 作为
static_assert
的条件你应该使用std::is_same_v
(或者std::is_same<...>::value
代替。
作为替代方案,您可以只提供容器,而不是键、值和模板容器:
template <typename Container>
class Registry
{
using ID = typename Container::key_type;
using Value = typename Container::mapped_type;
static_assert(std::is_same_v<Container, std::map<ID, Value>>
|| std::is_same_v<Container, std::unordered_map<ID, Value>>,
"Underlying storage type must be a std::map-ish.");
// ...
};
随着使用
Registry<std::map<std::size_t, bool>> testRegistry;
Registry<std::unordered_map<std::size_t, float>> testRegistry2;