I am trying to detect at compile time if some classes do have the 'equals to' operator defined. I don't understand the behavior of the following snippet:
#include <iostream>
#include <vector>
#include <experimental/type_traits>
template<typename T>
using SupportsEqualsToOp_t = decltype(std::declval<T>().operator==(std::declval<T>()));
template<typename T>
using SupportsEqualsToFree_t = decltype(std::declval<T>() == std::declval<T>());
template<typename T>
struct A{};
int main() {
std::vector<int> v0{1,2,3};
std::vector<int> v1{1,2,3};
//std::cout << v0==v1 << std::endl; // this does not compile
std::cout << std::experimental::is_detected_v<SupportsEqualsToOp_t, std::vector<int>> << std::endl;
std::cout << std::experimental::is_detected_v<SupportsEqualsToFree_t, std::vector<int>> << std::endl;
std::cout << std::experimental::is_detected_v<SupportsEqualsToOp_t, A<int>> << std::endl;
std::cout << std::experimental::is_detected_v<SupportsEqualsToFree_t, A<int>> << std::endl;
return 0;
}
Which gives:
0
1
0
0
Whereas I would expect to have:
0
0
0
0
Why std::vector
does not behave as A
here?
You've messed up your operator precedence. std::cout << v0
doesn't compile, nor would (std::cout << v0) == v1
Not only that, your SupportsEqualsToFree_t
finds any ==
, not just free function ==
.
If you want specifically free function ==
, you need something like
template<typename T>
using SupportsEqualsToOp_t = decltype(std::declval<T>().operator==(std::declval<T>()));
template<typename T>
using SupportsEqualsToFree_t = decltype(operator==(std::declval<T>(), std::declval<T>()));
template<typename T>
using SupportsEqualsTo_t = decltype(std::declval<T>() == std::declval<T>());