如何创建类型列表的笛卡尔积?

2023-12-05

我想使用可变参数模板创建类型列表的叉积。

这是我到目前为止所拥有的:

#include <iostream>
#include <typeinfo>
#include <cxxabi.h>

template<typename...> struct type_list {};

template<typename T1, typename T2> struct type_pair {};

template<typename T, typename... Rest>
  struct row
{
  typedef type_list<type_pair<T,Rest>...> type;
};

template<typename... T>
  struct cross_product
{
  typedef type_list<typename row<T,T...>::type...> type;
};

int main()
{
  int s;
  typedef cross_product<int, float, short>::type result;
  std::cout << abi::__cxa_demangle(typeid(result).name(), 0, 0, &s) << std::endl;

  return 0;
}

该程序输出:

$ g++ -std=c++0x cross_product.cpp ; ./a.out 
type_list<type_list<type_pair<int, int>, type_pair<int, float>, type_pair<int, short> >, type_list<type_pair<float, int>, type_pair<float, float>, type_pair<float, short> >, type_list<type_pair<short, int>, type_pair<short, float>, type_pair<short, short> > >

但我希望它输出:

type_list<type_pair<int,int>, type_pair<int,float>, type_pair<int,short>, type_pair<float,int>,...>

也就是说,没有嵌套type_lists.

有没有一种直接的方法可以做到这一点而不需要row助手,或者解决方案应该“解开”嵌套的type_list不知何故?


我认为一个不错的干净版本:

cross_product.cpp:

#include "type_printer.hpp"

#include <iostream>

template<typename ...Ts> struct type_list {};
template<typename T1, typename T2> struct pair {};

// Concatenation
template <typename ... T> struct concat;
template <typename ... Ts, typename ... Us>
struct concat<type_list<Ts...>, type_list<Us...>>
{
    typedef type_list<Ts..., Us...> type;
};

// Cross Product
template <typename T, typename U> struct cross_product;

// Partially specialise the empty case for the first type_list.
template <typename ...Us>
struct cross_product<type_list<>, type_list<Us...>> {
    typedef type_list<> type;
};

// The general case for two type_lists. Process:
// 1. Expand out the head of the first type_list with the full second type_list.
// 2. Recurse the tail of the first type_list.
// 3. Concatenate the two type_lists.
template <typename T, typename ...Ts, typename ...Us>
struct cross_product<type_list<T, Ts...>, type_list<Us...>> {
    typedef typename concat<
        type_list<pair<T, Us>...>,
        typename cross_product<type_list<Ts...>, type_list<Us...>>::type
    >::type type;
};

struct A {};
struct B {};
struct C {};
struct D {};
struct E {};
struct F {};

template <typename T, typename U>
void test()
{
    std::cout << print_type<T>() << " \u2a2f " << print_type<U>() << " = "
        << print_type<typename cross_product<T, U>::type>() << std::endl;
}

int main()
{
    std::cout << "Cartesian product of type lists\n";
    test<type_list<>, type_list<>>();
    test<type_list<>, type_list<A>>();
    test<type_list<>, type_list<A, B>>();
    test<type_list<A, B>, type_list<>>();
    test<type_list<A>, type_list<B>>();
    test<type_list<A>, type_list<B, C, D>>();
    test<type_list<A, B>, type_list<B, C, D>>();
    test<type_list<A, B, C>, type_list<D>>();
    test<type_list<A, B, C>, type_list<D, E, F>>();
    return 0;
}

类型_打印机.hpp:

#ifndef TYPE_PRINTER_HPP
#define TYPE_PRINTER_HPP

#include "detail/type_printer_detail.hpp"

template <typename T>
std::string print_type()
{
    return detail::type_printer<T>()();
}

#endif

详细信息/type_printer_detail.hpp:

#ifndef DETAIL__TYPE_PRINTER_DETAIL_HPP
#define DETAIL__TYPE_PRINTER_DETAIL_HPP

#include <typeinfo>
#include <cxxabi.h>
#include <string>

template <typename ...Ts> struct type_list;
template <typename T1, typename T2> struct pair;

namespace detail {

// print scalar types
template <typename T>
struct type_printer {
    std::string operator()() const {
        int s;
        return abi::__cxa_demangle(typeid(T).name(), 0, 0, &s);
    }   
};

// print pair<T, U> types
template <typename T, typename U>
struct type_printer<pair<T, U>> {
    std::string operator()() const {
        return "(" + type_printer<T>()() + "," + type_printer<U>()() + ")";
    }   
};

// print type_list<T>
template <>
struct type_printer<type_list<>> {
    std::string operator()() const {
        return "\u2205";
    }   
};

template <typename T>
struct type_printer<type_list<T>> {
    std::string operator()() const {
        return "{" + type_printer<T>()() + "}";
    }   
    std::string operator()(const std::string& sep) const {
        return sep + type_printer<T>()();
    }   
};

template <typename T, typename ...Ts>
struct type_printer<type_list<T, Ts...>> {
    std::string operator()() const {
        return "{" + type_printer<T>()() + type_printer<type_list<Ts...>>()(std::string(", ")) + "}";
    }   
    std::string operator()(const std::string& sep) const {
        return sep + type_printer<T>()() + type_printer<type_list<Ts...>>()(sep);
    }   
};
}

#endif

Run:

g++ -std=c++0x cross_product.cpp && ./a.out

Output:

Cartesian product of type lists
∅ ⨯ ∅ = ∅
∅ ⨯ {A} = ∅
∅ ⨯ {A, B} = ∅
{A, B} ⨯ ∅ = ∅
{A} ⨯ {B} = {(A,B)}
{A} ⨯ {B, C, D} = {(A,B), (A,C), (A,D)}
{A, B} ⨯ {B, C, D} = {(A,B), (A,C), (A,D), (B,B), (B,C), (B,D)}
{A, B, C} ⨯ {D} = {(A,D), (B,D), (C,D)}
{A, B, C} ⨯ {D, E, F} = {(A,D), (A,E), (A,F), (B,D), (B,E), (B,F), (C,D), (C,E), (C,F)}

(我注意到在使用 Chrome 的 Windows 上,跨积 unicode 字符显示得不太好。抱歉,我不知道如何解决这个问题。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建类型列表的笛卡尔积? 的相关文章

随机推荐

  • 使用powershell登录后如何从网站获取表数据?

    我的公司希望我从他们的内部网站获取数据 对其进行组织 然后将其发送到数据库 数据显示在您在站点内导航到的表格上 我想将这些字段提取到文件或内存中以进行进一步处理 到目前为止 我可以通过获取提交登录按钮的 ID 并传递我的用户名 密码来在 p
  • ffmpeg通过python子进程无法找到相机

    这里有一个奇怪的问题 我使用这个命令通过 ffmpeg 捕获我的网络摄像头 通过 Windows 上的 cmd ffmpeg y t 300 rtbufsize 1024M f dshow i video Lenovo EasyCamera
  • 视图需要相互依赖的逻辑:没有模型是否可行?

    我正在尝试编写一些 Oracle 11g SQL 但遇到了一些先有鸡还是先有蛋的问题 我正在寻找类似电子表格的行为 我找到了一个使用 Oracle 的解决方案MODEL条款 但性能并不好 所以我想知道是否 非MODEL 解决方案在技术上甚至
  • 在 django 项目中导入应用程序

    我在 django 项目中的另一个应用程序中导入应用程序时遇到问题 我知道有几个关于这个主题的问题 asnwsers 相信我 我读了很多 甚至还有一些关于 python import 的 这是我的项目树 我将放置真实的文件夹名称 was f
  • 将 URL 变量传递到 xsl 中

    是否可以将 URL 变量传递到 xsl xml 中 例如 http www somedomain com index aspx myVar test myVar2 anotherTest 我希望能够在 xsl 文件的逻辑中使用 myVar
  • 在 Nifi 中从 Avro Schema 创建 Postgresql 表

    使用 InferAvroSchema 我获得了文件的 Avro 架构 我想使用此 Avro 架构在 PostregSql 中创建一个表 我必须使用哪个处理器 我使用 GetFile gt InferAvroSchema gt 我想从此架构创
  • ItemsControl 调整大小时边框消失(使用“stretchpanel”)

    昨天我问如何让 ItemsControl 使其子项均匀分布在可用空间中 在愉快地阅读答案后 我写了 实际上是复制并调整了它 我自己的 stretchpanel 它正是我想要的 然而 我的孩子应该在右侧有一个边框 只要孩子比其内容大 它就可以
  • 与 python pandas 中的melt相反

    我不知道如何在 python 中使用 Pandas 进行 反向熔化 这是我的起始数据 label type value 0 x a 1 1 x b 2 2 x c 3 3 y a 4 4 y b 5 5 y c 6 6 z a 7 7 z
  • 如何解决 AMD 路径冲突?

    我正在尝试使用Esri ArcGis JavaScript API 其加载方式为Dojo using dojo require 我有一个现有的模块化AMD requirejs我需要将此代码集成到其中的 Typescript 应用程序 在初始
  • 如何获取点击“赞”按钮的用户的 Facebook ID?

    有没有办法获取在我自己的网站上点击社交插件的 赞 按钮的用户的 Facebook ID 尽管我花了一整天的时间寻找它 但我找不到任何方法 据我所知 您不可能知道谁点击了 喜欢 按钮 但是如果用户通过您的网站登录 Facebook 意味着您编
  • Spring-React frontend-maven-plugin 不工作

    我正在关注的文档是https spring io guides tutorials react and spring data rest 构建一个使用 Spring 的 React 应用程序 spring 部分很好 直到到达建议使用插件安装
  • Android 回收器视图中的水平和垂直滚动

    我有一个要求 我需要在回收器视图中进行水平滚动和垂直滚动 它基于来自服务器的数据类型 如果服务器的响应将第一个元素作为数组 我需要将其放在水平滚动列表中 如果第二个元素是单个对象 那么我需要将其显示在卡片中 同样 顺序会发生变化 并应反映在
  • Excel VBA 项目未关闭

    我有一个 COM 插件 在其中处理 Excel 事件 我点击Alt F11查看与Excel相关的VBA项目 但是 当我关闭工作簿时 项目资源管理器中的 Excel VBA 项目也没有关闭 当我的 COM 插件未安装时 它会正常关闭 发生了什
  • .NET MVC 4 JSON Post/Put Web.config 中的字符限制

    我使用 PUT 动词将 JSON 发送到 MVC 控制器 当我达到某个限制时 我会收到 500 错误 如果我缩小发送的 JSON 那么它发送得很好 有谁知道 web config 中的配置允许将更大量的 JSON 传递到我的应用程序吗 答案
  • Power Query - 从单列到整个表的数据转换

    我有一个要求 我有一张这样的桌子 实际表有 2 列 Column1 Column2 ColAValue ColBValue New Row ColCValue Above Row ColCValue2 Above Row ColDValue
  • 我们可以在EF中进行交叉连接吗?

    所以基本上我回来时问了这个问题 查询包含对不同数据上下文中定义的项目的引用 但这次我是在 EF 中进行的 EF是否支持两个表之间的交叉连接 您无法在不同的数据上下文之间进行连接 您必须使用 linq objects 进行连接 var cro
  • 在 JWASM/MASM 中 - pshufw 产生错误 A2030:当前 CPU 模式下不接受指令或寄存器

    我有以下汇编程序 在编译时出现错误 686 mmx model flat c code MmxAdd proc push ebp mov ebp esp mov eax ebp 24 cmp eax AddOpTableCount jae
  • 使用 Angular2 将文件上传到 REST API

    实际上 我正在开发一个 Spring REST API 其接口是用 Angular 2 编码的 我的问题是我无法使用 Angular 2 上传文件 我的java网络资源是 RequestMapping method RequestMetho
  • 如何将浏览器重定向到 ASP.NET 中的本地文件?

    我想要火狐浏览器打开C somefile txt在本地驱动器上 我尝试过使用 file 前缀的response redirect 但它只是插入 对象移到此处 进入页面 我还想对路径进行 htmlencode 因为它可能包含特殊字符 Edit
  • 如何创建类型列表的笛卡尔积?

    我想使用可变参数模板创建类型列表的叉积 这是我到目前为止所拥有的 include