title: Implicit conversion of lefthand argument in in-class declared friend operator
body: <p>I am using CRTP to provide template-argument dependent addition of functions to a class, in this case the addition of <code>operator +</code> and <code>operator +=</code>, using the template class <code>ImplAdd</code>. For the former, implicit conversions should be performed on both arguments, which means I have to use an in-class friend operator like this:</p>
  
  <pre><code>template&lt;class Type, bool active&gt;
  struct ImplAdd{
      virtual int get_val_() const = 0;
      virtual void set_val_(int) = 0;
  };
  
  //if activated is true, the operators + and += will be defined
  template&lt;class Type&gt;
  class ImplAdd &lt; Type, true &gt; {
      virtual int get_val_() const = 0;
      virtual void set_val_(int) = 0;
      Type* this_(){ return (Type*)this; }
  public:
      Type&amp; operator +=(const Type&amp; x){
          set_val_(get_val_() + x.get_val_());
          return *this_();
      }
  
      //This should enable conversions on the lefthand argument
      friend Type&amp; operator+(const Type&amp; lhs, const Type&amp; rhs){
          Type ret = lhs;
          return ret += rhs;
      }
  };
  </code></pre>
  
  <p>This is needed because classes that actually inherit from <code>ImplAdd</code> define constant values and a unique value type for those constants, much like a scoped enum.</p>
  
  <pre><code>//by using true as the template argument, the operators + and += will be defined
  class MyEnum : public ImplAdd&lt;MyEnum, true&gt;{
      int get_val_() const override{
          return (int)value;
      }
      void set_val_(int v) override{
          value = (ValueT)v;
      }
  public:
      enum class ValueT{
          zero, one, two
      };
  private:
      typedef  int UnderlyingT;
      ValueT value;
  public:
      static const ValueT zero = ValueT::zero;
      static const ValueT one = ValueT::one;
      static const ValueT two = ValueT::two;
      MyEnum(ValueT x) : value(x){}
      MyEnum(const MyEnum&amp; other) : value(other.value){}
  };
  </code></pre>
  
  <p>From my perspective, the following code should now easily compile, but it doesn't.</p>
  
  <pre><code>int main(int argc, char* argv[])
  {
      MyEnum my = MyEnum::zero;                //works
      my += MyEnum::one;                       //works
      my = MyEnum(MyEnum::zero) + MyEnum::two; //works
      my = MyEnum::zero + MyEnum(MyEnum::two); //ERROR C2676
      my = MyEnum::zero + MyEnum::two;         //ERROR C2676
      MyEnum my2 = my + my;                    //works
      return 0;
  }
  </code></pre>
  
  <p>For both lines marked with C2676, the following error message is printed:</p>
  
  <pre><code>error C2676: binary '+' : 'const MyEnum::ValueT' does not define this operator or a conversion to a type acceptable to the predefined operator
  </code></pre>
  
  <p>What am I doing wrong? Isn't the use of defining an operator as an in-class friend the common way to enable implicit conversion on both arguments? If not, how can I do it in this case?</p>