mercredi 14 septembre 2016

Multiple specialization with poorman's enable_if_t

Somehow, overload II never get used.

How to specialize an operator overload for different traits?

By the way, I only have an ancient standard library on the target machine because the linux kernel is very old.

The program is compiled with icc trait.cpp -std=c++11

Thanks.

trait.cpp:

#include <iostream>
#include "trait.hpp"
    //cut and paste from standard library
    //I don't have new version of std now.

class A; // forward declaration.

///////////////////////
//Define some traits //
///////////////////////
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 {};

/////////////////
// Test Object //
/////////////////
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=(T1 & input){
            //Overload I
            val = 2*input;
        }
        template <typename T1>
        enable_if_t<is_A<T1>::value,void>
        operator=(A & Bb){
            //Overload II
            val = 5*Bb.val;
        }
};

///////////////////
// Main Function //
///////////////////

int main(void){
    A Aa;
    A Bb;
    int in_a = 3;
    int in_b = 7;
    Aa = in_a;
    Bb = Aa; //Actually Overload I instead of Overload II
             //is used. This leads to an error.
    Aa.print();
    Bb.print();
}

trait.hpp:

template<bool B, class T = void>
struct enable_if_t {}; 
template<class T>
struct enable_if_t<true, T> { typedef T type; };

template<class T, T v>
struct integral_constant {
    constexpr static T value = v; //constexpr
    typedef T value_type;
    typedef integral_constant type;
    constexpr operator value_type() const { //constexpr
        noexcept return value;
    }
    constexpr const value_type operator()() const { //constexpr
        noexcept return value;
    }
};
typedef integral_constant<bool,true> true_type;
typedef integral_constant<bool,false> false_type;

Compiler Output:

trait.cpp(32): error: no operator "*" matches these operands
            operand types are: int * A
              val = 2*input;
                     ^
          detected during instantiation of "enable_if_t<is_int<T1>::value, void> A::operator=(T1 &) [with T1=A]" at line 52

compilation aborted for trait.cpp (code 2)

Aucun commentaire:

Enregistrer un commentaire