Overloading operator of an inner template class

I try to overload operator== of the template class which is inner for another template class.

template <typename T>
class Outer {
 public:
  template <bool IsConst>
  class Inner {
   public:
    friend bool operator==(const Inner<true>&, const Inner<true>&);
  };

  Inner<true> get() {
    Inner<true> ret;
    return ret;
  }
};

template <typename T>
bool operator==(const typename Outer<T>::template Inner<true>& first,
                const typename Outer<T>::template Inner<true>& second) {
  return true;
}

int main() {
  Outer<int> var;
  Outer<int>::Inner<true> inner = var.get();
  bool result = inner == inner;
}

But the compiler refuses to compile my code, output the following:

Undefined symbols for architecture x86_64:
  "operator==(Outer<int>::Inner<true> const&, Outer<int>::Inner<true> const&)", referenced from:
      _main in main.cpp.o

How can I solve this problem?

>Solution :

The problem is that the friend declaration that you’ve provided is a nontemplate friend declaration.

How can I solve this problem?

By adding a separate template parameter clause for the friend declaration as shown below and using a default argument for the template parameter U.

template <typename T>
class Outer {
 public:
  template <bool IsConst>
  class Inner {
   public:
   //add a separate parameter clause and provide the definition
   template <typename U=T>
   friend bool operator==(const typename Outer<U>::template Inner<true>& first,
                const typename Outer<U>::template Inner<true>& second){return 1;}
  };
 
  Inner<true> get() {
    Inner<true> ret;
    return ret;
  }
};
int main() {
  Outer<int> var;
  Outer<int>::Inner<true> inner = var.get();
  bool result = inner == inner;   //works now 
}

Working demo


Method 2

Note that it is also possible to define the friend function inside the class without make it a template.

template <typename T>
class Outer {
 public:
  template <bool IsConst>
  class Inner {
   public:

    friend bool operator==(const Inner<true>&, const Inner<true>&)
    {
        return true;
    }
  };

  Inner<true> get() {
    Inner<true> ret;
    return ret;
  }
};



int main() {
  Outer<int> var;
  Outer<int>::Inner<true> inner = var.get();
  bool result = inner == inner;


  Outer<char> var2;
  Outer<char>::Inner<true> inner2 = var2.get();
  bool result2 = inner2 == inner2;
}

Leave a Reply