从两个lambda的函数返回lambda时的链接器错误

时间:2017-08-13 18:52:07

标签: c++ lambda linker-errors eigen

最近,我一直在使用JS canvas来制作二维和三维的分形。现在,我正在通过SDL和Eigen将我的项目移植到C ++中。能够编写函数供以后使用非常重要。下面的代码是我第一次尝试制作复合函数工厂:

std::function< Eigen::Vector3f(Eigen::Vector3f) > compose3d(std::function< 
Eigen::Vector3f(Eigen::Vector3f) > a, std::function< 
Eigen::Vector3f(Eigen::Vector3f) > b){
    return [&](Eigen::Vector3f vec)->Eigen::Vector3f{
        return b(a(vec));
    };
}

目前,这在链接期间给出了重复的符号错误。如果删除此代码,则错误消失。我确保此函数位于标题的ifndef部分内。我知道在头文件中完全定义函数不是最佳实践,但是希望在重构之前使事情正常工作。

总的来说,我只是想知道这个问题是否在编写函数时是错误的,如果我应该在我的代码中的其他地方查找重复定义。我知道创建函数指针列表而不是创建函数列表被认为更好,我将在解决此链接器错误后继续实现它。

对不起,如果这是可怕的,我没有写C ++很长时间,这是我第一次尝试lambda。

谢谢!

2 个答案:

答案 0 :(得分:0)

声明它“内联”。否则,包含头文件的每个文件都将创建一个带有该签名的单独函数。

答案 1 :(得分:0)

链接问题很可能是因为您在头文件中有函数定义,该文件包含在多个编译单元中。这会导致重复的定义错误。您需要将声明移动到单个编译中(只在头文件中留下声明),或者创建函数staticinline,它允许在不同的编译单元中进行多个定义。

更大的问题是你通过引用函数参数绑定然后返回带有绑定引用的lambda。函数返回后,这些引用将变为悬空,当您尝试调用返回的lambda时,会导致未定义的行为。这是一个特别有害的错误,因为它可能适用于简单的示例和测试程序(内联所有内容),并且对于更复杂的情况会失败。

要解决此问题,您需要按值而不是按引用绑定参数 - 使用[=]代替[&]