使用模板从类型列表提升类型
Promote type from a list of types, with templates
我有一个带有int元素的vector和一个带有float元素的vector。在这种情况下,大多数首选类型是float,在点积中,我想返回float类型(如果没有指定)。
下面的代码就是这样做的,但是模板包出了问题。
你能帮我一点忙吗?
#include <iostream>
#include <vector>
#include <array>
using namespace std;
template<typename Tp, typename T1> struct contains
{
constexpr static bool value = std::is_same<Tp, T1>::value;
};
template<typename Tp, typename T1, typename ... Tn> struct contains
{
constexpr static bool value = std::is_same<Tp, T1>::value || contains<Tp, Tn...>::value;
};
template<typename ... T> struct perfect
{
typedef
typename std::conditional<contains<long double, T...>::value, long double,
typename std::conditional<contains<double , T...>::value, double,
typename std::conditional<contains<float , T...>::value, float,
typename std::conditional<contains<long long , T...>::value, long long,
typename std::conditional<contains<unsigned long long, T...>::value, unsigned long long,
typename std::conditional<contains<int , T...>::value, int,
typename std::conditional<contains<unsigned int, T...>::value, unsigned int,
//.....
void
>>>>>>>::type type;
};
struct Vector1 : public std::vector<double> {};
struct Vector2 : public std::vector<int> {};
struct Vector3 : public std::vector<float> {};
template<typename C1, typename C2, typename T = perfect<typename C1::value_type, typename C2::value_type>::type>
T dot_product(const C1 &c1, const C2 &c2)
{
return 0; // return c1 * c2
}
int main()
{
Vector1 a;
Vector2 b;
cout << dot_product(a, b) << endl;
cout << dot_product<Vector1, Vector2, long double>(a, b) << endl;
}
你错过了两件事。
template<typename Tp, typename T1> struct contains
{
constexpr static bool value = std::is_same<Tp, T1>::value;
};
是专门化,所以应该是
template<typename Tp, typename T1> struct contains<T1,Tp>
// ^^^^^^
{
constexpr static bool value = std::is_same<Tp, T1>::value;
};
,应该在原模板之后定义。
接下来,您在这里缺少了typename。
template<typename C1, typename C2, typename T = typename perfect<typename C1::value_type, typename C2::value_type>::type>
// ^^^^^^^
然而,我应该提一下,你可能在这里把它复杂化了。我不确定这一切是否有必要从两种类型中推导出来。也许预处理宏可以为您做得更好。我假设这是一次练习。
编辑:
这是一个类似的操作,但不同的方法,从c++模板完整指南。老了,但仍然足够你的选择
#define MK_PROMOTION(T1,T2,Tr)
template<> class Promotion<T1, T2> {
public:
typedef Tr type;
};
template<> class Promotion<T2, T1> {
public:
typedef Tr type;
};
template<typename T1, typename T2>
class Promotion {
public:
typedef T1 type;
};
template<typename T>
class Promotion<T,T> {
public:
typedef T type;
};
MK_PROMOTION(int, char, int)
MK_PROMOTION(double, float, double)
MK_PROMOTION(double, int, double)
typedef std::vector<double> Vector1;
typedef std::vector<int> Vector2;
typedef std::vector<float> Vector3;
template<typename C1, typename C2, typename T = typename Promotion< typename C1::value_type, typename C2::value_type >::type >
T dot_product(const C1 &c1, const C2 &c2)
{
return 0; // return c1 * c2
}
int main()
{
Vector1 a;
Vector2 b;
cout << dot_product(a, b) << endl;
cout << dot_product<Vector1, Vector2, long double>(a, b) << endl;
}
你要找的是decltype<C1() * C2()>
,不需要你的struct perfect
。
编辑: decltype()
它更好。
template<typename C1, typename C2, typename T = decltype(typename C1::value_type() * typename C2::value_type())>
T dot_product(const C1 &c1, const C2 &c2) { return 5; }
修正了未来社区需要的程序:(许多语法错误)
#include <iostream>
#include <vector>
using namespace std;
template<typename Tp, typename T1, typename ... Tn> struct contains_type
{ constexpr static bool value = std::is_same<Tp, T1>::value || contains_type<Tp, Tn...>::value; };
template<typename Tp, typename T1> struct contains_type<Tp, T1>
{ constexpr static bool value = std::is_same<Tp, T1>::value; };
template<typename ... T> struct type_promotion
{
typedef typename
std::conditional<contains_type<long double, T...>::value, long double,
typename std::conditional<contains_type<double , T...>::value, double,
typename std::conditional<contains_type<float , T...>::value, float,
typename std::conditional<contains_type<long long , T...>::value, long long,
typename std::conditional<contains_type<unsigned long long, T...>::value, unsigned long long,
typename std::conditional<contains_type<int , T...>::value, int,
typename std::conditional<contains_type<unsigned int, T...>::value, unsigned int,
void>::type>::type>::type>::type>::type>::type>::type type;
};
struct Vector1 : public std::vector<double> {};
struct Vector2 : public std::vector<int> {};
template<typename C1, typename C2, typename T = typename type_promotion<typename C1::value_type, typename C2::value_type>::type>
T dot_product(const C1 &c1, const C2 &c2)
{ return 5; }
int main()
{
Vector1 a;
Vector2 b, c;
cout << dot_product(a, b) / 2 << endl;
cout << dot_product(b, c) / 2 << endl;
cout << dot_product<Vector1, Vector2, long double>(a, b) << endl;
}
相关文章:
- 使用简单类型列表实现的指数编译时间.为什么
- 从类型列表中递归删除重复项会导致编译器堆空间错误 (VS2017)
- 测试两个类型列表中的所有组合
- 谷歌测试:模板模板的笛卡尔乘积的类型列表与模板
- 在迭代模板类型列表时无法停止递归
- 将可变参数类型列表的扩展打包为复杂类型的初始值设定项列表 - 合法吗?
- 阅读从 istream 到矢量的不同类型列表
- 如何在C++中创建类型列表的 n 路笛卡尔积?
- c++17通过生成预先声明的类型列表的笛卡尔乘积来生成std::变体
- 将变量模板限制为类型列表
- 我可以使用特征指定变体的类型列表吗?
- 如何对要用于模板参数的类型列表进行编码
- 创建类型列表并访问每种类型的静态成员?
- 为什么BOOST :: HANA :: EXAREMIS ::键入实验功能?类型列表的棘手是什么
- 如果创建支持返回可变参数类型列表的通用模板 API,我应该使用 std::tuple 还是其他东西?
- std::仅移动类型列表:不能在 VC++ 中放入 std::vector
- C++类型列表创建子列表
- 调用STD ::功能,并带有变体类型列表
- 在没有宏的情况下在 C++98 中创建类型列表时遇到问题
- 如何从类型列表重建参数包