1

我有一个带有 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;
}
4

3 回答 3

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>
                                             // ^^^^^^^ 

但是我应该提到你可能在这里过于复杂了。我不确定是否所有这些都是从两种类型中扣除所必需的。也许预处理器宏可以为您做得更好。我假设这是一个练习。



编辑:好的,这是一个与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;
}
于 2013-04-23T12:46:16.077 回答
1

你正在寻找decltype<C1() * C2()>,不需要你的struct perfect

于 2013-04-23T12:54:00.053 回答
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;
}
于 2013-04-23T18:21:32.017 回答