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
, assignsstd::forward<Ui>(std::get<i>(u))
toget<i>(*this)
.
Return reference and value inside std::tuple
You can use std::make_tuple
and pass a reference_wrapper
For each
Ti
inTypes...
, the corresponding typeVi
inVTypes...
isstd::decay<Ti>::type
unless application ofstd::decay
results instd::reference_wrapper<X>
for some typeX
, in which case the deduced type isX&
.
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
How to Get Python Exception Text
How to Declare Array with Auto
Is There Any G++ Option to Dump Class Layout and Vtables
How to Embed a Http Server in a Google Chrome Extension
Which Sorting Algorithm Is Used by Stl's List::Sort()
Visual Studio 2013 Error Ms8020 Build Tools V140 Cannot Be Found
How to Pre-Allocate Space for a File in C/C++ on Windows
Symbol Visibility and Namespace
Linking Boost Library with Boost_Use_Static_Lib Off on Windows
Memset for Initialization in C++
How to Simulate Interfaces in C++
Visualising 4D Objects in Opengl
Why Do Some Includes Need the .H and Others Not
Where How to Use List Initialization
Clear Data Inside Text File in C++
Why Does Enumwindows Return More Windows Than I Expected
Why Can't You Do Bitwise Operations on Pointer in C, and Is There a Way Around This