c++ - 指向 lambda 函数的函数指针相等

标签 c++ c++17

我想知道 C++ 标准是否保证以下行为(请参阅断言)? 它似乎在最新版本的 clang 和 gcc 下工作,但我仍然不确定它的标准定义行为或实现是否定义了一个。

#include <cassert>
#include <functional>

struct test
{
    using fn_ptr_t = int(*)(int);

    fn_ptr_t fn_ = nullptr;

    template<auto Fun>
    void assign() noexcept
    {
        fn_ = +[](int i)
        {
            return std::invoke(Fun, i);
        };
    }
};

int fun(int i) { return i; }
int gun(int i) { return i; }

int main()
{
    test t0, t1, t2;

    t0.assign<&fun>();
    t1.assign<&fun>();
    t2.assign<&gun>();

    assert(t0.fn_ == t1.fn_);
    assert(t0.fn_ != t2.fn_);

    return 0;
}

我发现标准中关于函数指针的描述如下:

C++03 5.10/1 [expr.eq]: ... Pointers to objects or functions of the same type (after pointer conversions) can be compared for equality. Two pointers of the same type compare equal if and only if they are both null, both point to the same function, or both represent the same address (3.9.2).

但是,我不确定当函数指针指向 lambda 函数时是什么情况,因为据说 lambda 每次都是唯一对象。

最佳答案

你说得对,lambda 是唯一的,这正是第二个断言通过的原因。但它们在每次评估时并不总是不同:

template <typename>
auto get() { return []{}; }

auto l1 = get<int>();
auto l2 = get<long>();
auto l3 = get<int>();

static_assert(std::is_same_v<decltype(l1), decltype(l2)>); // fails
static_assert(std::is_same_v<decltype(l1), decltype(l3)>); // passes

// caveat: needs C++20
l1 = l2; // no, different lambdas
l1 = l3; // ok, same lambda

在你的例子中,t0 的函数指针和 t1是一样的,因为它们都是由 assign<&fun> 赋值的,其中 lambda 始终具有相同的类型。

因为它们具有相同的类型,所以它们具有相同的 operator()因此两个函数指针是相同的(它们指向相同的 operator() )。

关于c++ - 指向 lambda 函数的函数指针相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54397435/

相关文章:

c++ - 如何在不同线程中同时运行多个 QDialogs?

python - 最小工作示例 tensorflow 服务客户端

c++ - 在 IDE 外运行时出现 QNetworkReply::UnknownNetworkError

c++ - Docker 远程 API JSON 架构定义

c++ - 是否可以在编译时检测函数的默认参数?

c++ - 为什么 createProcess() 中的 argv 与普通的 C++ 程序不同

c++ - 为什么 `std::reference_wrapper` 在 c++17 中弃用并在 c++20 中删除?

C++17 operator==() 和 operator!=() 代码在 C++20 中失败

c++ - 使用指令和部分特化

c++ - 返回的std::function保留在std::variant的映射中