从两个 lambda 函数返回 lambda 时出现链接器错误
Linker error on returning lambda from function of two lambdas
最近一直在用JScanvas制作二维和三维的分形。现在,我正致力于通过 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));
};
}
目前这在链接期间给我一个重复的符号错误。如果删除此代码,错误就会消失。我已确保此函数位于我的 header 的 ifndef
部分中。我知道在 header 中完全定义函数不是最佳实践,但希望在重构之前让事情正常进行。
总的来说,如果我应该在我的代码中的其他地方查找重复定义,我只想知道这个问题是否是函数编写中的错误。我知道创建函数指针列表比创建函数列表更好,我将在解决此链接器错误后着手实现它。
对不起,如果这太可怕了,我写 C++ 的时间并不长,这是我第一次尝试 lambda。
谢谢!
声明它"inline"。否则,包含头文件的每个文件都将创建一个具有该签名的单独函数。
链接问题很可能是因为您在包含在多个编译单元中的头文件中有函数定义。这会导致重复定义错误。您需要将声明移动到单个编译(仅在头文件中保留声明),或者使函数 static
或 inline
,这允许在不同的编译单元中进行多个定义。
一个更大的问题是您通过引用绑定到函数参数,然后 return 具有绑定引用的 lambda。这些引用将在函数 return 之后变为悬空,从而导致在您尝试调用 returned lambda 时出现未定义的行为。这是一个特别有害的错误,因为它可能适用于简单的示例和测试程序(内联所有内容),而适用于更复杂的情况。
要解决这个问题,您需要按值而不是按引用来绑定参数——使用 [=]
而不是 [&]
。
最近一直在用JScanvas制作二维和三维的分形。现在,我正致力于通过 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));
};
}
目前这在链接期间给我一个重复的符号错误。如果删除此代码,错误就会消失。我已确保此函数位于我的 header 的 ifndef
部分中。我知道在 header 中完全定义函数不是最佳实践,但希望在重构之前让事情正常进行。
总的来说,如果我应该在我的代码中的其他地方查找重复定义,我只想知道这个问题是否是函数编写中的错误。我知道创建函数指针列表比创建函数列表更好,我将在解决此链接器错误后着手实现它。
对不起,如果这太可怕了,我写 C++ 的时间并不长,这是我第一次尝试 lambda。
谢谢!
声明它"inline"。否则,包含头文件的每个文件都将创建一个具有该签名的单独函数。
链接问题很可能是因为您在包含在多个编译单元中的头文件中有函数定义。这会导致重复定义错误。您需要将声明移动到单个编译(仅在头文件中保留声明),或者使函数 static
或 inline
,这允许在不同的编译单元中进行多个定义。
一个更大的问题是您通过引用绑定到函数参数,然后 return 具有绑定引用的 lambda。这些引用将在函数 return 之后变为悬空,从而导致在您尝试调用 returned lambda 时出现未定义的行为。这是一个特别有害的错误,因为它可能适用于简单的示例和测试程序(内联所有内容),而适用于更复杂的情况。
要解决这个问题,您需要按值而不是按引用来绑定参数——使用 [=]
而不是 [&]
。