std::is_invocable 在模板类型上的意外结果

Iva*_*nov 7 c++ templates type-traits

if constexpr检查了一个类型是否与自身相等。我用std::is_invocable_v<std::equal_to<>, T, T>.

但是,当T是一个由不可比结构组成的向量时,该代码段错误地返回 True。有什么深层原因还是编译器错误?

最小的例子如下。

#include <type_traits>
#include <iostream>
#include <vector>

class TNonComparable{};

int main()
{
    std::cout << std::is_invocable_v<std::equal_to<>, TNonComparable, TNonComparable> << "\n";
    // 0

    std::cout << std::is_invocable_v<
            std::equal_to<>,
            std::vector<TNonComparable>,
            std::vector<TNonComparable>
        > << "\n";
    // 1

    std::vector<TNonComparable> vec;
    // vec == vec;
    // (expected) compilation error
}
Run Code Online (Sandbox Code Playgroud)

我检查了 Godbolt 的输出,所有最新版本的 g++ 和 clang 都是一样的。

Vas*_*lij 2

我认为,这是正确的行为。

首先检查类型中std::is_invokable_v是否存在。它不存在 - 因此结果为 0。operator==TNonComparable

在第二种情况下,std::is_invokable_v检查 的相等运算符std::vector,该运算符存在并且可以被调用。但如果尝试调用它,它将无法编译,因为该TNonComparable类型没有operator==. 但在你不尝试使用它之前,它不会产生错误。

也许,在第二种情况下,您应该检查 std::vector 的 value_type:

std::cout << std::is_invocable_v<
        std::equal_to<>,
        std::vector<TNonComparable>::value_type,
        std::vector<TNonComparable>::value_type
    > << "\n";
// 0
Run Code Online (Sandbox Code Playgroud)

  • @IvanSmirnov:“*你知道如何自动执行深度检查吗?*”你不能*制作*使用 SFINAE 而不使用 SFINAE 的东西。如果“vector”的相等运算符对 SFINAE 不友好,那么您对“vector”的相等运算符的测试也不会对 SFINAE 友好。最好只接受给定代码的限制并将这些限制转发给用户。 (2认同)