Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > C++0x - tuple

Reply
Thread Tools

C++0x - tuple

 
 
er
Guest
Posts: n/a
 
      06-01-2011
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
 
Reply With Quote
 
 
 
 
Rune Allnor
Guest
Posts: n/a
 
      06-01-2011
On Jun 1, 4:40*am, er <(E-Mail Removed)> wrote:
> 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
 
Reply With Quote
 
 
 
 
red floyd
Guest
Posts: n/a
 
      06-01-2011
On 5/31/2011 9:36 PM, Rune Allnor wrote:
> On Jun 1, 4:40 am, er<(E-Mail Removed)> wrote:
>> 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?
>


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

 
Reply With Quote
 
Qi
Guest
Posts: n/a
 
      06-01-2011
On 2011-6-1 10:40, er wrote:
> 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.

--
WQ
 
Reply With Quote
 
Saeed Amrollahi
Guest
Posts: n/a
 
      06-01-2011
On Jun 1, 7:36*am, Rune Allnor <(E-Mail Removed)> wrote:
> On Jun 1, 4:40*am, er <(E-Mail Removed)> wrote:
>
> > 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


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
 
Reply With Quote
 
Saeed Amrollahi
Guest
Posts: n/a
 
      06-01-2011
On Jun 1, 5:40*am, er <(E-Mail Removed)> wrote:
> 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
 
Reply With Quote
 
Balog Pal
Guest
Posts: n/a
 
      06-01-2011
"er" <(E-Mail Removed)>
> 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.

 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      06-01-2011
On 1 Jun., 04:40, er wrote:
>
> * * * 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
 
Reply With Quote
 
er
Guest
Posts: n/a
 
      06-01-2011
On Jun 1, 5:02*am, SG <(E-Mail Removed)> wrote:
> On 1 Jun., 04:40, er wrote:
>
>
>
> > ** * * 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.
>


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
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      06-01-2011
On 1 Jun., 15:21, er <(E-Mail Removed)> wrote:
> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
*tuple vs tuple example print os.path.join(os.path.dirname(os.tmpnam()),*("a","b","c")) Steve Python 1 12-13-2005 10:25 PM
Why tuple with one item is no tuple Gregor Horvath Python 37 03-30-2005 06:58 AM
Easily convert unicode tuple to python string tuple??? Michal Mikolajczyk Python 1 04-20-2004 08:37 PM
Re: Easily convert unicode tuple to python string tuple??? Jeff Epler Python 0 04-20-2004 03:36 PM
Re: Easily convert unicode tuple to python string tuple??? Bill Scherer Python 0 04-20-2004 03:34 PM



Advertisments