変数への参照を使用してブースト融合ベクトルを作成したいと考えています。目標は、さまざまな数のパラメーターを関数に渡し、それらを融合ベクトルに追加することです。参照型のため、すべての要素を TMP で一度に 1 つずつ追加します。ただし、融合ベクトルの一部の要素が間違っている場合があります。未定義の動作 (間違った値、読み取りアクセス違反) のようです。
理解を容易にするために、TMP で使用される再帰を「展開」した例を書きました。Fusion ベクトルに 2 つの参照を追加するだけで、結果が出力されます。
#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))));
では、上記の例にはバグが含まれているのでしょうか、それとも VC11 オプティマイザーに何か問題があるのでしょうか? ローカル ブースト フュージョン ビュー (boost::fusion::join はビューのみを返し、ビューは boost::fusion::vector で「通常の」boost::fusion::vector に変換されます) を別のビューに渡すことはできますか?値で機能しますか?