一个同时接受 std::vector 和 QVector 的函数模板?

2024-05-06

假设我有一个函数叫做loadData()它需要一个容器(填充数据)和一个 CSV 文件。我需要以下重载:

  1. loadData(std::vector<double>& data, const std::string& file);
  2. loadData(QVector<double>& data, const std::string& file);
  3. loadData(std::vector<std::complex<double>>& data, const std::string& file);
  4. loadData(QVector<std::complex<double>>& data, const std::string& file);
  5. loadData(std::vector<std::vector<double>>& data, const std::string& file);
  6. loadData(QVector<QVector<double>>& data, const std::string& file);
  7. loadData(std::vector<std::vector<std::complex<double>>>& data, const std::string& file);
  8. loadData(QVector<QVector<std::complex<double>>>& data, const std::string& file);

QVector是 Qt 的类向量类,具有类似的 API,但仅采用一个模板参数T(而不是两个,比如std::vector<T, A>).

1-4 的实现几乎相同(它只是调用 5-8,将单个向量包装在另一个向量(相同类型!)中。

5-8 的实现是相同的(只是调用 CSV 解析函数的适当重载)。

我可能还需要添加float过载,或QVector<std::vector<...>> / std::vector<QVector<...>>过载。

基本上,这是我想概括的一组巨大的重载。

是否可以将它们全部组合成 2 个函数模板(一个用于 1D 容器,另一个用于 2D 容器)?

Thanks


是否可以将它们全部组合成 2 个函数模板(一个用于 1D 容器,另一个用于 2D 容器)?

是的...需要一些工作,但相对简单。

也许有更简单的方法,但我建议创建一个自定义类型特征来验证模板模板是否是std::vector or QVector

template <template <typename...> class>
struct isVector : public std::false_type
 { };

template <>
struct isVector<std::vector> : public std::true_type
 { };

template <>
struct isVector<QVector> : public std::true_type
 { };

接下来另一个自定义类型特征来验证类型是否是浮点类型std::complex<T> type

template <typename T>
struct isCFloating : public std::is_floating_point<T>
 { };

template <typename T>
struct isCFloating<std::complex<T>> : public std::true_type
 { };

现在您可以编写矢量的矢量版本(该截距也混合std::vector/QVector情况)如下

template <template <typename ...> class V1,
          template <typename ...> class V2, typename T>
auto loadData (V1<V2<T>> & v, std::string fn)
   -> std::enable_if_t<   isVector<V1>::value
                       && isVector<V2>::value
                       && isCFloating<T>::value>
 {
   std::cout << "- vector of vector version, " << fn << std::endl;
 }

之后,简单的向量版本(包装第一个参数并调用向量的向量版本)变成

template <template <typename ...> class V, typename T>
auto loadData (V<T> & v, std::string fn)
   -> std::enable_if_t<isVector<V>::value && isCFloating<T>::value>
 {
   std::cout << "- vector version, " << fn << std::endl;

   V<V<T>> vv{1, v};

   loadData(vv, fn);
 }

我已经准备好了以下完整的工作示例,但是(抱歉)我目前没有可用的 QT 平台,所以我添加了一个假的QVector

#include <vector>
#include <complex>
#include <iostream>
#include <type_traits>

// fake QVector
template <typename>
struct QVector
 { 
   template <typename ... Ts>
   QVector (Ts const & ...)
    { }
 };

template <template <typename...> class>
struct isVector : public std::false_type
 { };

template <>
struct isVector<std::vector> : public std::true_type
 { };

template <>
struct isVector<QVector> : public std::true_type
 { };

template <typename T>
struct isCFloating : public std::is_floating_point<T>
 { };

template <typename T>
struct isCFloating<std::complex<T>> : public std::true_type
 { };


template <template <typename ...> class V1,
          template <typename ...> class V2, typename T>
auto loadData (V1<V2<T>> & v, std::string fn)
   -> std::enable_if_t<   isVector<V1>::value
                       && isVector<V2>::value
                       && isCFloating<T>::value>
 {
   std::cout << "- vector of vector version, " << fn << std::endl;
 }

template <template <typename ...> class V, typename T>
auto loadData (V<T> & v, std::string fn)
   -> std::enable_if_t<isVector<V>::value && isCFloating<T>::value>
 {
   std::cout << "- vector version, " << fn << std::endl;

   V<V<T>> vv{1, v};

   loadData(vv, fn);
 }

int main ()
 {
   std::vector<float>                             vf;
   std::vector<std::complex<float>>               vc;
   std::vector<std::vector<double>>               vvf;
   std::vector<std::vector<std::complex<double>>> vvc;
   QVector<long double>                           qf;
   QVector<std::complex<long double>>             qc;
   QVector<QVector<float>>                        qqf;
   QVector<QVector<std::complex<float>>>          qqc;

   loadData(vf,  "case  1");
   loadData(qf,  "case  2");
   loadData(vc,  "case  3");
   loadData(qc,  "case  4");
   loadData(vvf, "case  5");
   loadData(qqf, "case  6");
   loadData(vvc, "case  7");
   loadData(qqc, "case  8");

   // extra cases: mixing std::vector and QVector

   std::vector<QVector<double>>                    vqf;
   std::vector<QVector<std::complex<double>>>      vqc;
   QVector<std::vector<long double>>               qvf;
   QVector<std::vector<std::complex<long double>>> qvc;

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

一个同时接受 std::vector 和 QVector 的函数模板? 的相关文章

  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 将字符串从非托管代码传递到托管

    我在将字符串从非托管代码传递到托管代码时遇到问题 在我的非托管类中 非托管类 cpp 我有一个来自托管代码的函数指针 TESTCALLBACK FUNCTION testCbFunc TESTCALLBACK FUNCTION 接受一个字符
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • 基于范围的 for 循环中的未命名循环变量?

    有没有什么方法可以不在基于范围的 for 循环中 使用 循环变量 同时也避免编译器发出有关未使用它的警告 对于上下文 我正在尝试执行以下操作 我启用了 将警告视为错误 并且我不想进行像通过在某处毫无意义地提及变量来强制 使用 变量这样的黑客
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • .Net Core / 控制台应用程序 / 配置 / XML

    我第一次尝试使用新的 ConfigurationBuilder 和选项模式进入 Net Core 库 这里有很多很好的例子 https docs asp net en latest fundamentals configuration ht
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • Windows 窗体不会在调试模式下显示

    我最近升级到 VS 2012 我有一组在 VS 2010 中编码的 UI 测试 我试图在 VS 2012 中启动它们 我有一个 Windows 窗体 在开始时显示使用 AssemblyInitialize 属性运行测试 我使用此表单允许用户
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 方法参数内的变量赋值

    我刚刚发现 通过发现错误 你可以这样做 string s 3 int i int TryParse s hello out i returns false 使用赋值的返回值是否合法 Obviously i is but is this th
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var
  • 如何将字符串“07:35”(HH:MM) 转换为 TimeSpan

    我想知道是否有办法将 24 小时时间格式的字符串转换为 TimeSpan 现在我有一种 旧时尚风格 string stringTime 07 35 string values stringTime Split TimeSpan ts new

随机推荐