首页 > 解决方案 > 比较 std::functions 与存储在其中的 lambda 的相等性

问题描述

我正在使用以下函数来测试std::functions 的相等性。该功能的灵感来自此处的 SO 讨论

template<typename T, typename... U>
inline bool AreEqual(std::function<T(U...)> function_1, std::function<T(U...)> function_2) {

    typedef T(fnType)(U...);
    fnType ** f_ptr_1 = function_1.template target<fnType*>();
    size_t f1 = (size_t) *f_ptr_1;
    fnType ** f_ptr_2 = function_2.template target<fnType*>();
    size_t f2 = (size_t) *f_ptr_2;

    return (f1 == f2);
}

现在如果我有下面的测试来验证它的工作

#include "gtest/gtest.h"

void DummyFunc(bool value) {
    value = true;
}

TEST(Some_Test, verify_equality_of_std_functions) {
    typedef std::function<void(bool)> FuncType1;

    FuncType1 f2 = &DummyFunc;
    EXPECT_TRUE(AreEqual(f2, f2));  // This passes as expected

    auto test_lambda = [](bool dummy_param) {
        dummy_param = true;
    };

    FuncType1 f1 = test_lambda;
    EXPECT_TRUE(AreEqual(f1, f1));  // But, this causes a crash! Why?
}

为什么AreEqual在传递 lambda 时会崩溃?我对 lambda 做错了什么,还是AreEqual缺少比较存储在std::functions 中的 lambda 的逻辑?

标签: c++c++11lambdastd-function

解决方案


您可以使用以下功能来做到这一点。

template<class RET, class... Args>
inline bool AreEqual(RET(*f1)(Args&...), RET(*f2)(Args&...))
{
    return f1 == f2;
}

TEST(Some_Test, verify_equality_of_std_functions) {
    typedef std::function<void(bool)> FuncType1;

    FuncType1 f2 = DummyFunc;
    EXPECT_TRUE(AreEqual(*f2.target<void(*)()>(), *f2.target<void(*)()>())); 

    auto test_lambda = [](bool dummy_param) {
        dummy_param = true;
    };
    
    /* Lambdas are required to be converted to raw function pointers. */
    void(*f1)() = test_lambda;
    EXPECT_TRUE(AreEqual(f1, f1));
}

Lambda 不是std::function<>s。


推荐阅读