我有一个带有int元素的向量和一个带有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;
}
答案 0 :(得分:2)
你在这里缺少两件事。
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;
};
,应在原始模板之后定义。
接下来你在这里缺少类型名称。
template<typename C1, typename C2, typename T = typename perfect<typename C1::value_type, typename C2::value_type>::type>
// ^^^^^^^
但是我应该提一下,你可能在这里过于复杂。我不确定是否所有这些都是从两种类型中扣除所必需的。也许预处理器宏可以为您做得更好。我假设这是一个练习。
修改强>:
OK这是一个类似的操作,但与C++ Templates a Complete Guide的方法不同。虽然旧但仍足以满足您的需求
#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;
}
答案 1 :(得分:1)
您正在寻找decltype<C1() * C2()>
,不需要struct perfect
。
答案 2 :(得分:0)
编辑: 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;
}