Std::Make_Tuple Doesn't Make References

std::make_tuple doesn't make references

Try forward_as_tuple:

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

How to make a tuple of const references?

The first question is if this fits with the C++11 standard, and if it doesn't, then why?

This is expected behaviour. In the second case template argument deduction fails because there is no T so that tuple<const T&> becomes tuple<int&>.

In the first case it works because tuple<int&> is implicitly convertible to tuple<const int&>. This is a user-defined conversion and as such not considered during template argument deduction.

Your questions smells a bit like an X/Y problem. Consider posting the real question that made you look for a solution involving this kind of function template/tuple combination.

Your ctie function template looks fine. But keep in mind that things like

auto t = ctie(5);

will basically produce a dangling reference. So, you might want to restrict ctie to lvalues only.

What is the difference between assigning to std::tie and tuple of references?

The std::tie() function actually initializes the members of the std::tuple<T&...> of references where is the std::tuple<T&...> can't be initialized by a templatory std::tuple<T...>. The operation std::tie() does and initializing a corresponding object would be expressed like this:

std::tuple<int&, float&> test = 
std::tuple<int&, float&>(testint, testfloat) = std::make_tuple(testint, testfloat);

(obviously, you would normally use different values than those of the already bound variables).

Return std::tuple containing const-reference in C++11

Use std::get. It returns reference to stored element.

#include <iostream>
#include <tuple>

using MyType = int;
MyType some_internal_reference = 42;

std::tuple<const MyType&, bool> func()
{
return { some_internal_reference, true };
}

int main()
{
auto ret = func();
const MyType& obj = std::get<0>(ret);

std::cout << "before change: " << obj << '\n';

some_internal_reference = 7;

std::cout << "after change: " << obj << '\n';
}

It prints

before change: 42
after change: 7

Note, as per @StoryTeller-UnslanderMonica comment, don't use std::make_tuple in this case. It stores a decay (naked type) copy.

build issue with make_tuple - arrary reference

make_tuple will decay the arguments you pass to it before constructing the tuple, so the unsigned int(&)[5] type is converted to unsigned int *, which does not match your sha1 constructor's parameter type.

Use forward_as_tuple instead to create a tuple of references.

map.emplace(std::piecewise_construct,
std::forward_as_tuple(digest, 10),
std::forward_as_tuple("test"));

Assigning values to a tuple of references

Use std::make_tuple:

tup = std::make_tuple(1, 2.0);

There are special overloaded operator= for assigning different types of std::tuple:

template <class... UTypes>
tuple& operator=(const tuple<UTypes...>& u);

template <class... UTypes>
tuple& operator=(tuple<UTypes...>&& u);

The second one (which is the one that gets called here) does exactly what you want:

For all i, assigns std::forward<Ui>(std::get<i>(u)) to get<i>(*this).

Return reference and value inside std::tuple

You can use std::make_tuple and pass a reference_wrapper

For each Ti in Types..., the corresponding type Vi in VTypes... is std::decay<Ti>::type unless application of std::decay results in std::reference_wrapper<X> for some type X, in which case the deduced type is X&.

auto return_tuple_with_reference_and_value()
{
return std::make_tuple(std::ref(get_A()), 20);
}

Why does std::make_tuple turn std::reference_wrapper<X> arguments into X&?

This is more or less the primary purpose of reference_wrapper.

Normally, std::make_tuple always makes tuples of values (std::decay simulates pass-by-value semantics). Given int x, y; std::make_tuple(x, y); makes a std::tuple<int, int>, even though it will have deduced Types as a pack of references int&, int&. std::decay converts those to int, int.

reference_wrapper allows you to force creation of tuples of references: std::make_tuple(std::ref(x), y) will make a std::tuple<int&, int>.

Other parts of the standard library use reference_wrapper in the same way. As an example, std::bind will usually copy/move the bound arguments into the resulting object, but if you want it to store only a reference, you can explicitly request it by passing a reference_wrapper.



Related Topics



Leave a reply



Submit