我对 C++ 元编程/SFINAE 有点陌生,我在开发检查以查看传递给方法的类型是否包含在预定义类型列表中时遇到了麻烦。这里的上下文是我想检查在我的变体中注册的类型是否与另一个结构中的输出类型匹配。在我的应用程序中注册的每个项目都通过标签(某个数字)映射到另一个项目(在结构中)。我想创建一个类型映射,如果要注册的类型与我的有线协议(protocol)结构中的项目类型不匹配,可以在编译时使用它来引发断言。
所以像这样:
// register elements in type map:
type_map::register(ID_1, decltype(wire_type_item_1));
type_map::register(ID_2, decltype(wire_type_item_2));
... etc.
// and when types are registered
template<typename T>
void add_item(const uint32_t id, const T item)
{
// add static_assert here
// look up type based on ID, and compare to type passed in
// when add_item is called
static_assert(std::is_same<type_map::find(id), decltype(T),
"Attempted to register type that does not match wire type");
...
}
如果有任何关于从哪里开始/如何去做的指示,我将不胜感激 - 谢谢!
最佳答案
根据(和误解?)Yakk 在我的第一个回答中的评论中的建议(感谢),我编写了一种真正不同的(更简单、更优雅,恕我直言)方式来实现编译时映射。
首先是ct_pair
。现在使用 using
类型 type
(获取模板类型 T
参数)和 static
函数更加复杂即,给定结构的相同索引(包装在 std::integral_constant
中,以具有来自 ct_pair
的不同实现的不同类型)
template <std::size_t I, typename T>
struct ct_pair
{
using type = T;
static ct_pair get_pair (std::integral_constant<std::size_t, I>)
{ return {}; }
};
现在 std::tuple
、std::tuple_cat()
和辅助类 get_tuple
不再需要了, ct_map
就变成了
template <typename ... Ps>
struct ct_map : public Ps...
{
using Ps::get_pair...;
template <std::size_t I>
using find_type
= typename decltype(get_pair(
std::integral_constant<std::size_t, I>{}))::type;
};
现在完整的例子(不幸的是 C++17 而不是之前,当我的另一个答案应该是 C++11/C++14 兼容时)
#include <tuple>
#include <iostream>
#include <type_traits>
template <std::size_t I, typename T>
struct ct_pair
{
using type = T;
static ct_pair get_pair (std::integral_constant<std::size_t, I>)
{ return {}; }
};
template <typename ... Ps>
struct ct_map : public Ps...
{
using Ps::get_pair...;
template <std::size_t I>
using find_type
= typename decltype(get_pair(
std::integral_constant<std::size_t, I>{}))::type;
};
using type_map = ct_map<ct_pair<2u, char>,
ct_pair<3u, int>,
ct_pair<5u, long>,
ct_pair<7u, long long>>;
int main()
{
static_assert( std::is_same_v<type_map::find_type<5u>, long> );
}
关于c++ - 有没有办法在 C++17 中创建编译时类型映射以进行类型检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58367871/