我想通过特征进行以下特化。

  • Array Aa = Scalar in_a将使用overload I
  • Array Aa = Array Bb将使用overload II

  • 在以下代码中,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)
    }
    

    最佳答案

    这是简化的代码并按预期工作:

    #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)
    }
    

    10-04 18:19