2017-08-13 52 views
1

最近,我一直在JS畫布上做二維和三維分形。現在,我正在通過SDL和Eigen將我的項目移植到C++中。能夠編寫功能供以後使用非常重要。下面的代碼是我在做一個複合函數工廠第一次嘗試:從兩個lambda函數返回lambda的鏈接器錯誤

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。

謝謝!

+3

使函數'inline'?例如。請參閱https://stackoverflow.com/questions/5971736/c-inline-function – stijn

+1

這與lambda無關。 – 2017-08-13 19:08:24

+0

你不應該在頭文件中定義函數,這個錯誤就是爲什麼。這不是關於「最佳實踐」。 – melpomene

回答

0

聲明它「內聯」。否則,包含頭文件的每個文件都將使用該簽名創建一個單獨的函數。

0

鏈接問題很可能是因爲您在包含在多個編譯單元中的頭文件中具有函數定義。這會導致重複的定義錯誤。您需要將聲明移到單個編譯中(只在頭文件中留下聲明),或者創建函數staticinline,該函數允許在不同編譯單元中使用多個定義。

一個更大的問題是,你通過引用來綁定函數參數,然後返回帶有綁定引用的lambda。這些引用將在函數返回後變成懸掛,當您嘗試調用返回的lambda時導致未定義的行爲。這是一個特別有害的錯誤,因爲它可能適用於簡單的示例和測試程序(內置所有內容)並且在更復雜的情況下失敗。

要解決該問題,您需要通過值而不是通過引用來綁定參數 - 使用[=]而不是[&]