C++0x - tuple

E

er

Please, why the failed assertion below? Thanks.

#include <tuple>

int main()
{

std::tuple<int&&> t1( 1 );

assert( std::get<0>( t1 ) == 1 ); // OK

std::tuple<std::string, int&&> t2( "a", 1 );

assert( std::get<1>( t2 ) == 1 ); // Fail

return 0;
}

OS X 10.6 - GCC 4.4
 
R

Rune Allnor

Please, why the failed assertion below? Thanks.

#include <tuple>

int main()
{

            std::tuple<int&&> t1( 1 );

What type is 'int&&' ? The naive intrepretation is that it is
a reference to a reference. If so, isn't that illegal (or at
least UB)? Should this compile at all?

Rune
 
R

red floyd

What type is 'int&&' ? The naive intrepretation is that it is
a reference to a reference. If so, isn't that illegal (or at
least UB)? Should this compile at all?

I'm not fully up on my C++0x, but isn't it an rvalue-reference?
 
Q

Qi

std::get<1>( t2 )

How about trace out the value of std::get<1>( t2 )
to see why the assert failed?

The assert failed because the value is wrong,
so it makes sense to see the value.
 
S

Saeed Amrollahi

What type is 'int&&' ? The naive intrepretation is that it is
a reference to a reference. If so, isn't that illegal (or at
least UB)? Should this compile at all?

Rune

Hi

Actually, int&& is r-value reference. It's like traditional
l-value reference, but it can bind to r-value. Consider:
int i = 1; // referent (l-value)
int& ir = i; // ir is a reference to i
int& ir2 = int(); // error int() is a temporary object
// and it's r-value
int&& ir3 = int(); // OK: binding r-value reference to r-value
R-value reference is a foundation for a new feature of
C++0x, called move semantics.
You can use such feature in Visual Studio 2010 or
gcc 4.5.0 or above.

Regards,
-- Saeed Amrollahi
 
S

Saeed Amrollahi

Please, why the failed assertion below? Thanks.

#include <tuple>

int main()
{

            std::tuple<int&&> t1( 1 );

           assert( std::get<0>( t1 ) == 1 ); // OK

            std::tuple<std::string, int&&> t2( "a", 1 );

           assert( std::get<1>( t2 ) == 1 ); // Fail

           return 0;

}

OS X 10.6 - GCC 4.4

I ran you program under Ubuntu & gcc 4.6.0
with the following command
gcc -std=c++0x -pedantic tuple_test.c++ -o tuple_test
and it's OK. Actually with the following program:
#include <cassert>
#include <tuple>
#include <iostream>

int main()
{
using namespace std;
tuple<int&&> t1(1);
assert(get<0>(t1) == 1);
tuple<string, int&&> t2("a", 1);
assert(get<1>(t2) == 1);
cout << get<0>(t2) << '\t' << get<1>(t2) << '\n';
return 0;
}

I have the following output:
a 1

Regards,
-- Saeed Amrollahi
 
B

Balog Pal

er said:
Please, why the failed assertion below? Thanks.

#include <tuple>

int main()
{
std::tuple<int&&> t1( 1 );
assert( std::get<0>( t1 ) == 1 ); // OK
std::tuple<std::string, int&&> t2( "a", 1 );
assert( std::get<1>( t2 ) == 1 ); // Fail
return 0;
}

tuple is a value type. You try to use it with reference. That will not
likely work in general.

In particular your tuple will have a member of reference type, that will be
bound to a temporary. That temporary is destroyed at the end of the line, so
you have a dongling reference and attached undefined behavior on its use.

Lifetime of a reference extends the lifetime of the temporary if done
directly:
int && i1 = getI();
const int & i2 = getI();

But it does not happen if you pass the ref to a function -- including a
different object's constructor.
 
S

SG

      std::tuple<int&&> t1( 1 );

creates a tuple that stores a DANGLING REFERENCE since the temporary
int object storing the one will be destroyed "after the semicolon".
       assert( std::get<0>( t1 ) == 1 ); // OK

You're invoking undefined behaviour due to the danling reference.
      std::tuple<std::string, int&&> t2( "a", 1 );

       assert( std::get<1>( t2 ) == 1 ); // Fail

That's what you get for undefined behaviour. Plain and simple.

In both cases a temporary int object will be created which stores the
number 1 and will stop existing after the semicolon. Therefore, the
"reference member" of the tuple becomes invalid. Any access invokes
undefined behaviour.

Cheers!
SG
 
E

er

creates a tuple that stores a DANGLING REFERENCE since the temporary
int object storing the one will be destroyed "after the semicolon".


You're invoking undefined behaviour due to the danling reference.

Thanks, but this

std::cout << std::get<1> ( std::tuple<std::string, int&&>( "a",
1 ) ) << std::endl;

outputs 0, and this

assert(
std::get<1>(
std::tuple<std::string, int&&>( "a", 1 )
) == 1
);

fails
 
S

SG

Thanks, but this

  std::cout << std::get<1> ( std::tuple<std::string, int&&>( "a",
1 ) )  << std::endl;

outputs 0, and this

  assert(
       std::get<1>(
           std::tuple<std::string, int&&>( "a", 1 )
       ) == 1
  );

fails

Sorry, but I don't see why this would be the case and I'm not able to
reproduce this. See http://ideone.com/yxcIi

Cheers!
SG
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top