I found a bug in my code that only happens when I enable compiler optimizations -O1 or greater. I traced the bug and it seems that I can't use the boost type_erased adaptor on a boost transformed range when optimizations are enabled. I wrote this c++ program to reproduce it:
#include <iostream>
#include <vector>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/adaptor/type_erased.hpp>
using namespace boost::adaptors;
using namespace std;
int addOne(int b) {
return b + 1;
}
int main(int, char**) {
vector<int> nums{ 1, 2, 3 };
auto result1 = nums | transformed(addOne) | type_erased<int, boost::forward_traversal_tag>();
auto result2 = nums | transformed(addOne);
auto result3 = nums | type_erased<int, boost::forward_traversal_tag>();
for (auto n : result1)
cout << n << " ";
cout << endl;
for (auto n : result2)
cout << n << " ";
cout << endl;
for (auto n : result3)
cout << n << " ";
cout << endl;
}
When I run this program without any optimizations, I get the following output:
2 3 4
2 3 4
1 2 3
When I run it with the -O1 flag, I get the following:
1 1 1
2 3 4
1 2 3
I am using clang++ to compile it. The version of clang that I am using is:
Apple LLVM version 8.0.0 (clang-800.0.38)
I don't know if I am doing something wrong, or if it is a boost/clang bug.
edit:
Changed it to
type_erased<int, boost::forward_traversal_tag, const int>()
and it works now. The third template argument is the reference type, setting the reference to const prolongs the timespan of the temporary created by the transformed.