I was trying to pass a tuple of two different vectors as the attribute to a Spirit X3 rule. One sensible way to do this seemed to be to wrap these in a forward_as_tuple
, since I only want to pass the references. That worked out nicely, but I had to write a separat variable declaration and then pass it on since the non-const temporary lifetime rules would bite me otherwise.
In the end, I ended up writing something like as_const(std::forward_as_tuple(ourBoxes, scoreVals))
. By making the temporary const, I can pass it on. The temporary is const -- since all element types are references, that is more or less a given.
This makes me wonder, is there any design rationale for making the forward_as_tuple
return type non-const? Or put another way, how can you validly mutate a tuple of only reference types?
EDIT:
Added a proper example, below. This relates back to the fact that I want to use X3, and the attribute type in X3 is always a reference, so passing the attribute by value instead is not an option. The wider question is still, is there any reason for forward_as_tuple
having a non-const return type.
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/home/x3.hpp>
using namespace boost::spirit;
using namespace std;
// Coming in C++ 17
template <class T>
constexpr std::add_const_t<T>& as_const(const T& t) noexcept
{
return t;
}
int main()
{
int x, y;
string readme = "42 43";
// Doesn't work
// phrase_parse(readme.begin(), readme.end(), x3::int_ > x3::int_,
// x3::space, forward_as_tuple(x, y));
// Works:
phrase_parse(readme.begin(), readme.end(), x3::int_ > x3::int_,
x3::space, as_const(forward_as_tuple(x, y)));
// Is there any reason for forward_as_tuple not returning a const?
// i.e. some use case where forward_as_tuple HAS to return a non-const for
// proper operation
}