c++ - 有没有办法在 C++17 中创建编译时类型映射以进行类型检查?

标签 c++ c++17 template-meta-programming typechecking typemaps

我对 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::tuplestd::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/

相关文章:

c++使用CRTP为variaidic模板中的每种类型创建纯虚拟重载

c++ - QT C++应用程序在单一计时器中崩溃并连接

c++ - 在 C++ 中将一个 vector 转换为另一个具有不同大小的 vector

c++ - 3个过程的严格交替

c++ - 如果是左值则引用,如果是右值则复制一份,即使右值持久化

c++ - 带有重载转换函数的 std::transform

c++ - "enum class"是 C++ 中的类类型吗?

c++ - 在C++中使循环变量成为常量

c++ - 非类型模板特化

compiler-construction - C++0x TMP编译速度