使用 std::experimental::is_detected_v 检测自由 '==' 运算符:std 类 的不同行为

Detection of free '==' operator using std::experimental::is_detected_v : different behavior for std classes

我试图在编译时检测某些 类 是否定义了 'equals to' 运算符。我不明白以下代码段的行为:

#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;
}

给出:

0
1
0
0

而我希望有:

0
0
0
0

为什么 std::vector 在这里的行为与 A 不同?

您弄乱了运算符的优先级。 std::cout << v0 不编译,(std::cout << v0) == v1

也不编译

不仅如此,您的 SupportsEqualsToFree_t 还能找到任何 ==,而不仅仅是自由函数 ==

如果你想要特别免费的功能==,你需要像

这样的东西
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>());

See it live