[Development] C++11 decltype magic with a container?

Stephen Kelly stephen.kelly at kdab.com
Fri May 24 10:19:30 CEST 2013


Hi Olivier,

Thanks for the suggestions.

On Thursday, May 23, 2013 17:58:49 Olivier Goffart wrote:

> > First, the operator== should be outside of the class. (or as a friend
> > function)

QList and QVector have equality comparison member functions. They can't be 
changed to free functions anyway until Qt 6. It also doesn't help the fact 
that stl containers report false positives (and therefore would no longer 
compile after my patch).

> You could do:
> 
> friend template <typename X> auto operator==(const Container<X> &c1
>                                              const Container<X> &c2)
>           -> decltype(c1.t == c2.t)    {...}

This does indeed work.

I investigated whether it would be possible to solve the problem while still 
using the op==() member funtion. Again, this doesn't help the stl case, but 
would probably help for the Qt containers.

The code below emits the expected result:

stephen at hal:~/cpp$ ./a.out 
0
0
1
1
0
0
1
1


#include <iostream>

template<typename T, typename U = bool>
struct HasEqualityComparison
{
  typedef void Result;
  enum { value = false };
};

template<typename T>
struct HasEqualityComparison<T, decltype(std::declval<T&>() == 
std::declval<T&>())>
{
  typedef bool Result;
  enum { value = true };
};

template<typename T>
struct Container {
  T t;

  auto
  operator==(const Container &other) const -> decltype(typename 
HasEqualityComparison<T>::Result())
  {
    return t == other.t;
  }
};

struct A {

};

struct B {
  bool operator==(const B &other)
  {
    return true;
  }
};

int main()
{
  std::cout << HasEqualityComparison<A>::value << std::endl;
  std::cout << HasEqualityComparison<Container<A>>::value << std::endl;
  std::cout << HasEqualityComparison<B>::value << std::endl;
  std::cout << HasEqualityComparison<Container<B>>::value << std::endl;
  std::cout << HasEqualityComparison<Container<A>>::value << std::endl;
  std::cout << HasEqualityComparison<Container<Container<A>>>::value << 
std::endl;
  std::cout << HasEqualityComparison<Container<B>>::value << std::endl;
  std::cout << HasEqualityComparison<Container<Container<B>>>::value << 
std::endl;
  return 0;
}


Thanks,

-- 
Stephen Kelly <stephen.kelly at kdab.com> | Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3636 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20130524/17b49f13/attachment.bin>


More information about the Development mailing list