问题描述
假设我有一个名为 c > / std :: vector< QVector< ...>> 重载。
I may also need to add float overloads, or QVector<std::vector<...>> / std::vector<QVector<...>> overloads.
基本上,这是一个我想归纳出大量的重载。
Basically, it's a huge set of overloads that I'd like to generalize.
是否可以将所有重载组合成2个函数模板(一个用于1D容器,另一个用于2D容器)?
Is it possible to combine all of them into maybe 2 function templates (one for 1D containers, another for 2D containers)?
谢谢
推荐答案
是...需要一些工作,但是相对简单。
Yes... require a little work but is relatively simple.
也许有更简单的方法,但是我建议创建一个自定义类型特征,以验证模板模板是否为 std :: vector 或 QVector
Maybe there are simpler methods but I propose the create a custom type traits that verify if a template-template is 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 { };
下一个自定义类型特征可以验证类型是否为<$ c $的浮点类型c> std :: complex< T> 类型
Next another custom type traits to verify if a type is a floating point type of a 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 情况),如下所示
Now you can write the vector-of-vector version (that intercept also mixed std::vector/QVector case) as follows
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; }
,然后是简单的矢量版本(包装第一个参数并调用向量版本)变成
and, after, the simple vector version (that wrap the first argument and call the vector-of-vector version) become
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
I've prepared the following full working example but (sorry) I don't have a QT platform available at the moment so I have added a fake 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"); }
这篇关于同时接受std :: vector和QVector的函数模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!