针对不同的特征专门针对相同的运算符

时间:2016-09-14 18:44:08

标签: c++ c++14 template-specialization typetraits

我希望通过特征专业化来完成以下任务。

  1. Array Aa = Scalar in_a会使用overload I

  2. Array Aa = Array Bb会使用overload II

  3. 在以下代码中,overload II永远不会被使用。

    有人提到T1无法推断overload II

    如何解决这个问题?

    我使用C ++ shell用C ++ 14编译代码。

    #include <iostream>
    #include <type_traits>
    
    using namespace std;
    class A; // forward declaration.
    
    template <typename T>
    struct is_A : false_type {};
    template <> struct is_A<A> : true_type {};
    
    template <typename T>
    struct is_int : false_type {};
    template <> struct is_int<int> : true_type {};
    template <> struct is_int<long> : true_type {};
    
    class A{
        public:
            int val;
            void print(void){
                std::cout << val << std::endl;
            }
            template <typename T1>
            enable_if_t<is_int<T1>::value,void>
            operator=(const T1 & input){
                val = 2*input; //Overload I
            }
            template <typename T1>
            enable_if_t<is_A<T1>::value,void>
            operator=(const T1 & Bb){
                val = 5*Bb.val; //Overload II
            }
    };
    
    int main(void){
        A Aa;
        A Bb;
        int in_a = 3;
        Aa = in_a; //This uses overload I as intended.
        Bb = Aa; //I want this to use overload II, but
                 //actually overload I is used.
                 //This leads to an error during compilation.
        Aa.print(); //This should give 6. (3x2)
        Bb.print(); //This should give 30. (6x5)
    }
    

3 个答案:

答案 0 :(得分:2)

您的代码应为

template <typename T>
std::enable_if_t<is_int<T>::value, A&>
operator=(const T& input){
    val = 2 * input; //Overload I
    return *this;
}
template <typename T>
std::enable_if_t<is_A<T>::value, A&>
operator=(T& rhs){
    val = 5 * rhs.val; //Overload II
    return *this;
}

Demo

但在你的情况下甚至更简单

A& operator=(int input){
    val = 2 * input; //Overload I
    return *this;
}

A& operator=(const A& rhs){
    val = 5 * rhs.val; //Overload II
    return *this;
}

答案 1 :(得分:2)

以下是您的代码简化并按预期工作:

#include <iostream>
#include <type_traits>
#include<utility>

class A;

template <typename T>
struct is_A : std::false_type {};
template <> struct is_A<A> : std::true_type {};

template <typename T>
struct is_int : std::false_type {};
template <> struct is_int<int> : std::true_type {};
template <> struct is_int<long> : std::true_type {};

class A{
public:
    int val;

    void print(void){
        std::cout << val << std::endl;
    }

    template <typename T1>
    std::enable_if_t<is_int<std::decay_t<T1>>::value, void>
    operator=(T1 && input){
        val = 2*std::forward<T1>(input);
    }

    template <typename T1>
    std::enable_if_t<is_A<std::decay_t<T1>>::value,void>
    operator=(T1 && Bb){
        val = 5*std::forward<T1>(Bb).val;
    }
};

int main(void){
    A Aa;
    A Bb;
    int in_a = 3;
    Aa = in_a;
    Bb = Aa;
    Aa.print(); //This should give 6. (3x2)
    Bb.print(); //This should give 30. (6x5)
}

答案 2 :(得分:1)

你真的需要所有模板魔法来处理你的简单案例吗?

#include <iostream>

class A;

class A{
public:
    int val;

    void print(void){
        std::cout << val << std::endl;
    }

    void operator =(const A& in){ val = in.val*5; }
    void operator =(int in) { val = in*2; }
};


int main(void){
    A Aa;
    A Bb;
    Aa = 3;
    Bb = Aa;
    Aa.print(); //This should give 6. (3x2)
    Bb.print(); //This should give 30. (6x5)
    return 0;
}