tuple example create c++ reference tuples c++11

create - tuple c++ example



std:: make_tuple no hace referencias (6)

He estado experimentando con std::tuple en combinación con referencias:

#include <iostream> #include <tuple> int main() { int a,b; std::tuple<int&,int&> test(a,b); std::get<0>(test) = 1; std::get<1>(test) = 2; std::cout << a << ":" << b << std::endl; // doesn''t make ref, not expected auto test2 = std::make_tuple(a,b); std::get<0>(test2) = -1; std::get<1>(test2) = -2; std::cout << a << ":" << b << std::endl; int &ar=a; int &br=b; // why does this not make a tuple of int& references? can we force it to notice? auto test3 = std::make_tuple(ar,br); std::get<0>(test3) = -1; std::get<1>(test3) = -2; std::cout << a << ":" << b << std::endl; }

De los tres ejemplos aquí, los dos primeros funcionan como se esperaba. El tercero sin embargo no lo hace. Esperaba que el auto tipo ( test3 ) fuera el mismo que el tipo de test (es decir, std::tuple<int&,int&> ).

Parece que std::make_tuple no puede hacer automáticamente tuplas de referencias. Por qué no? ¿Qué puedo hacer para que este sea el caso, aparte de construir algo de ese tipo explícitamente?

(El compilador era g ++ 4.4.5, usando 4.5 no lo cambia )


¿Qué pasa con std::make_tuple<int&, int&>(a, b);

Es cierto que, en cierto modo, make_shared el propósito, pero para funciones como make_shared aún obtienes beneficios.

Advertencia, no he intentado compilar esto, pero creo que funcionará.


En C ++ 14, puedes proceder así:

template<typename ...T, size_t... I> auto make_rtuple_helper(std::tuple<T...>& t , std::index_sequence<I...>) -> std::tuple<T&...> { return std::tie(std::get<I>(t)...) ;} template<typename ...T> std::tuple<T&...> make_rtuple( std::tuple<T...>& t ) { return make_rtuple_helper( t, std::make_index_sequence<sizeof...(T)>{}); }

Vea cómo funciona aquí en coliru: http://coliru.stacked-crooked.com/a/a665130e17fd8bcc

Saludos AA


Para el por qué: los parámetros de make_tuple se pasan por referencia const ( const T& ), por lo que si pasa int& , T coincide con int . Si dedujera que T fuera int& , el parámetro sería const T&& , y obtendrías un error de compilación.


Prueba forward_as_tuple :

auto test3 = std::forward_as_tuple(ar,br);


Qué tal si:

auto test3 = std::make_tuple(std::ref(a),std::ref(b));


std::tie hace referencias no const .

auto ref_tuple = std::tie(a,b); // decltype(ref_tuple) == std::tuple<int&, int&>

Para referencias const , también querrá la función de envoltorio std::cref :

auto cref_tuple = std::make_tuple(std::cref(a), std::cref(b));

O use un ayudante simplemente as_const para calificar las variables antes de pasarlas a std::tie :

template<class T> T const& as_const(T& v){ return v; } auto cref_tuple = std::tie(as_const(a), as_const(b));

O, si desea obtener fantasía, escriba su propio ctie (reutilizando std::tie y as_const ):

template<class... Ts> std::tuple<Ts const&...> ctie(Ts&... vs){ return std::tie(as_const(vs)...); } auto cref_tuple = ctie(a, b);