1

I am using gcc 4.8.4 with -std=c++11

Originally I have this simplified minimum code below ( since the definition of function is quite complex, I implemented template class definition outside of class declaration ).

#include <type_traits>
#include <iostream>


template< class A, class B >
class HAHA
{
  public :

    HAHA( void );
    ~HAHA( void );
    HAHA( const HAHA & o );

    void set_value( int i ) { _inner_value = i;    }
    int  value    ( void  ) { return _inner_value; }

    HAHA & operator= ( const HAHA & o );
    HAHA   operator+ ( const A    & o );
    HAHA   operator+ ( const B    & o );

  private :
    int _inner_value;
};

template< class A, class B >
HAHA< A, B >::HAHA( void )
  : _inner_value( 0 )
{
}


template< class A, class B >
HAHA< A, B >::~HAHA( void )
{
}


template< class A, class B >
HAHA< A, B >::HAHA( const HAHA & o )
  : _inner_value( o._inner_value )
{
}


template< class A, class B >
HAHA< A, B > &
HAHA< A, B >::operator= ( const HAHA & o )
{
  _inner_value = o._inner_value;
  return *this;
}


template< class A, class B >
HAHA< A, B >
HAHA< A, B >::operator+( const A & o )
{
  HAHA res;
  res._inner_value = _inner_value + o;
  return res;
}


template< class A, class B >
HAHA< A, B >
HAHA< A, B >::operator+( const B & o )
{
  HAHA res;
  res._inner_value = _inner_value + o;
  return res;
}



int test1( )
{
  HAHA< int, long > hehe;
  hehe.set_value( 3 );

  HAHA< int, long > hi;

  hi = hehe + int(4);

  std::cout << hi.value( ) << std::endl;
  return 0;
}


int test2( )
{
  HAHA< int, int > hehe;
  hehe.set_value( 3 );

  HAHA< int, int > hi;

  hi = hehe + 4;

  std::cout << hi.value( ) << std::endl;
  return 0;
}


int main( )
{
  return test2( );
}

The code above can run test1, but in test2, there is an ambiguous in instantiating. However, I need both oprator+ functions to work in other tests. So I cannot just remove one operator+ function. After some learning, I was told that I should use std::enable_if together with std::is_same. So I changed my code like :

template< class A, class B >
class HAHA
{
  public :

    ...
    HAHA operator+ ( const A & o );
    typename std::enable_if< !std::is_same< A, B >::value, HAHA >::type
    operator+ ( const B & o );
    ...
};
...
template< class A, class B >
typename std::enable_if< !std::is_same< A, B >::value, HAHA<A,B> >::type   <-- error reported that this line is not right
HAHA< A, B >::operator+( const B & o )
{
  HAHA res;
  res._inner_value = _inner_value + o;
  return res;
}

And then I got this error :

test_meta.cpp: In instantiation of ‘class HAHA<int, int>’:
test_meta.cpp:82:20:   required from here
test_meta.cpp:57:1: error: no type named ‘type’ in ‘struct std::enable_if<false, HAHA<int, int> >’
 HAHA< A, B >::operator+( const B & o )
 ^

How should I change my code ? many thanks!!!!

It is said that Selecting a member function using different enable_if conditions is similar to my problem. However, what I want is to disable a function while the two input type is the same. And I want to implement the definition outside of the class declaration. THX!

pavio
  • 11
  • 2
  • 1
    Possible duplicate of [Selecting a member function using different enable\_if conditions](https://stackoverflow.com/questions/13401716/selecting-a-member-function-using-different-enable-if-conditions) or https://stackoverflow.com/questions/11531989/what-happened-to-my-sfinae-redux-conditional-template-class-members – walnut Nov 17 '19 at 04:49
  • The basic answer is that you can't use `::std::enable_if` to make decisions about the existence of non-template member functions. Your member function is a member of a template, but it isn't a template itself. The question this is marked as a duplicate of gives you a technique for using `::std::enable_if` to accomplish what you want. – Omnifarious Nov 17 '19 at 04:55
  • 1
    You need a separate set of template parameter for both at your class definition and your template member function. Take a look at this [pastebin code](https://pastebin.com/ubDwCcEb) I modified and tested for you. Notice changes inside `class`, and at your member function for `operator+ (const B& o)`. – haxpor Nov 17 '19 at 05:03
  • thx, i will read the link – pavio Nov 17 '19 at 05:03
  • @haxpor, Many thx!!! – pavio Nov 17 '19 at 05:05
  • 1
    @Omnifarious, many thx!! – pavio Nov 17 '19 at 05:05

0 Answers0