Update: See full answer below. The short answer is no, not directly. You can create an indirect link using std::reference_wrapper or perform a more general effect with pointers (but without syntactic sugar and additional link security).
I ask because tuples make convenient variational memory in C ++ 11. It is theoretically reasonable for one element of a tuple to contain a link to another element in one tuple. (Replace the "link" with "pointer", and it works in practice.) The devil is the details of constructing such a tuple. Consider the following example:
#include <tuple>
The second element in t1 tuple refers to the automatic variable a instead of the first element in t1 . Is there a way to build a tuple so that one element of the tuple can contain a link to another element in the same tuple? I know that you could achieve this result by creating a tuple of links, for example:
int main() { A a; B b(a); std::tuple<A &, B &> t2 = std::tie(a, b); a.val = 24; std::cout << std::get<0>(t2).val << "\n";
But for my purposes, this is a hoax, as the second element in t2 still refers to an object that lives outside the tuple. The only way I can think that it compiles, but may contain undefined behavior [Edited to display a more concise example provided by Howard Hinnant]:
int main() { std::tuple<A, B> t3( A(), B(std::get<0>(t3)) ); // undefined behavior? std::get<0>(t3).val = 24; std::cout << std::get<0>(t3).val << "\n"; std::cout << std::get<1>(t3).val() << "\n"; // nasal demons? }
Edit: here is a minimal test program that returns with non-zero exit status when compiling using g ++ 4.7 with -O2 or higher. This assumes either undefined behavior or an error in gcc.
#include <tuple> class Level1 { public: Level1() : _touched(false), _val(0) { } void touch() { _touched = true; } double feel() { if ( _touched ) { _touched = false; _val = 42; } return _val; } private: bool _touched; double _val; }; class Level2 { public: Level2(Level1 &level1) : _level1(level1) { } double feel() { return _level1.feel(); } private: int _spaceholder1; double _spaceholder2; Level1 &_level1; }; class Level3 { public: Level3(Level2 &level2) : _level2(level2) { } double feel() { return _level2.feel(); } private: Level2 &_level2; }; int main() { std::tuple<Level3, Level2, Level1> levels( Level3(std::get<1>(levels)), Level2(std::get<2>(levels)), Level1() ); std::get<2>(levels).touch(); return ! ( std::get<0>(levels).feel() > 0 ); }
c ++ undefined-behavior c ++ 11 tuples
Benjamin kay
source share