我想創建一個帶有變量引用的boost融合向量。目標是將函數傳遞給函數,並將它們添加到融合向量中。由於引用類型,我使用TMP每次添加一個元素。但是有時融合向量中的某些元素是錯誤的。這看起來像未定義的行爲(錯誤的值,讀取訪問衝突)。
我寫了一個例子,其中我展開了在TMP中使用的遞歸以便於理解。它只是兩個引用添加到融合載體,並輸出結果:添加對boost :: fusion :: vector的引用
#include <iostream>
#include <boost/ref.hpp>
#include <boost/fusion/algorithm.hpp>
#include <boost/fusion/container.hpp>
using namespace boost;
using namespace boost::fusion;
//add second element
template <typename T>
vector<int&, double&> createVector2(T vec, double& v2) {
auto newVector = join(vec, make_vector(ref(v2)));
return newVector;
}
//add first element
template <typename T>
vector<int&, double&> createVector(T vec, int& v1, double& v2) {
auto newVector = join(vec, make_vector(ref(v1)));
return createVector2(newVector, v2);
}
int main() {
int v1 = 10;
double v2 = 15.3;
vector<> vec;
auto ret = createVector(vec, v1, v2);
std::cout << at_c<0>(ret) << std::endl;
std::cout << at_c<1>(ret) << std::endl;
if (at_c<0>(ret) != v1) {
std::cout << "FAILED" << std::endl;
}
if (at_c<1>(ret) != v2) {
std::cout << "FAILED" << std::endl;
}
return 0;
}
程序崩潰,當在升壓融合載體的引用被訪問(讀取訪問衝突),首先在這一行:
std::cout << at_c<0>(ret) << std::endl;
我使用VC11作爲編譯器(版本17.00.51106.1)。該錯誤僅在發佈模式下。但是當我使用VC10,GCC 4.7.0或GCC 4.7.2時,沒有錯誤,程序工作得很好。
要獲得VC11的工作方案,我有這條線
auto newVector = join(vec, make_vector(ref(v1)));
改變
auto newVector = as_vector(join(vec, make_vector(ref(v1))));
因此,沒有上面的例子中存在一個bug或者是有什麼不對的VC11優化?它允許傳遞一個本地boost視圖(boost :: fusion :: join只返回一個視圖,並且視圖被boost :: fusion :: vector轉換爲一個'normal'boost :: fusion :: vector)到另一個視圖函數的價值?