Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Temporary Objects

41 views
Skip to first unread message

Mark

unread,
Jul 1, 2016, 11:33:58 PM7/1/16
to

Consider

# include <iostream>
# include <string>


template < typename UnsignedType,
unsigned Width = 0 >
struct Test {

typedef UnsignedType ValueType;
ValueType mLocalVar;
unsigned int const mAddrLocation ;

Test ( unsigned int const addrLocation )
: mLocalVar ( 0 )
, mAddrLocation ( addrLocation )
{}

Test & operator= ( ValueType val )
{
//stuff
return ( *this );
}
};
typedef Test < volatile unsigned int, 32 > TestINT ;

int main()
{
unsigned int argument = 15 ;
unsigned int value = 5 ;
TestINT( 5 ) = value ;
TestINT ( argument ) = value ; //FAILS
return EXIT_SUCCESS ;
}


The line marked FAILS generate errors

error: conflicting declaration ‘TestINT argument’
error: ‘argument’ has a previous declaration as ‘unsigned int argument’
unsigned int argument = 15 ;

Unclear why. Thoughts?

Paavo Helde

unread,
Jul 2, 2016, 3:35:56 AM7/2/16
to
On 2.07.2016 6:33, Mark wrote:>
> Consider
>
> # include <iostream>
> # include <string>
>
>
> template < typename UnsignedType,
> unsigned Width = 0 >
> struct Test {
>
> typedef UnsignedType ValueType;
> ValueType mLocalVar;
> unsigned int const mAddrLocation ;
>
> Test ( unsigned int const addrLocation )
> : mLocalVar ( 0 )
> , mAddrLocation ( addrLocation )
> {}
>
> Test & operator= ( ValueType val )
> {
> //stuff
> return ( *this );
> }
> };
> typedef Test < volatile unsigned int, 32 > TestINT ;

Side note: volatile is generally not useful for anything nowadays
(unless you deal with hardware registers).

>
> int main()
> {
> unsigned int argument = 15 ;
> unsigned int value = 5 ;
> TestINT( 5 ) = value ;
> TestINT ( argument ) = value ; //FAILS
> return EXIT_SUCCESS ;

Side note: EXIT_SUCCESS requires #include <stdlib.h>

> }
>
>
> The line marked FAILS generate errors
>
> error: conflicting declaration ‘TestINT argument’
> error: ‘argument’ has a previous declaration as ‘unsigned int argument’
> unsigned int argument = 15 ;
>
> Unclear why. Thoughts?
>

C (and thus also C++) syntax allows parens around the variable names in
the declarations, so the line is actually equivalent to:

TestINT argument = value ;

To disambiguate it, one can change the lvalue name 'argument' to a
rvalue expression:

TestINT ( +argument ) = value ;

Cheers
Paavo







Mark

unread,
Jul 2, 2016, 10:51:41 AM7/2/16
to
On Saturday, July 2, 2016 at 3:35:56 AM UTC-4, Paavo Helde wrote:
> TestINT ( +argument ) = value ;
Don't recall seeing this before. Thanks

I have a follow up question. I'm trying to initialize the static vector within the class. But I'm getting the error:

error: default argument for template parameter for class enclosing ‘Test<UnsignedType, Width>::addrValueVec’
ADDR_VALUE_VEC Test < UnsignedType, Width >::addrValueVec ;

The code:
template < typename UnsignedType,
unsigned Width = 0 >
struct Test {

typedef UnsignedType ValueType;
ValueType mLocalVar;
unsigned int const mAddrLocation ;

typedef std::vector < std::pair < unsigned int, unsigned int > > ADDR_VALUE_VEC ;
static ADDR_VALUE_VEC addrValueVec ;

Test ( unsigned int const addrLocation )
: mLocalVar ( 0 )
, mAddrLocation ( addrLocation )
{}

Test & operator= ( ValueType val )
{
//stuff
return ( *this );
}

};
typedef Test < volatile unsigned int, 32 > TestINT ;

template < typename UnsignedType, unsigned Width = 0 >
ADDR_VALUE_VEC Test < UnsignedType, Width >::addrValueVec ;

Paavo Helde

unread,
Jul 2, 2016, 1:19:50 PM7/2/16
to
On 2.07.2016 17:51, Mark wrote:
> On Saturday, July 2, 2016 at 3:35:56 AM UTC-4, Paavo Helde wrote:
>> TestINT ( +argument ) = value ;
> Don't recall seeing this before.

This is because you are writing weird code (creating an unused temporary).

> Thanks
>
> I have a follow up question. I'm trying to initialize the static vector within the class. But I'm getting the error:
>
> error: default argument for template parameter for class enclosing ‘Test<UnsignedType, Width>::addrValueVec’
> ADDR_VALUE_VEC Test < UnsignedType, Width >::addrValueVec ;
>
> The code:
> template < typename UnsignedType,
> unsigned Width = 0 >
> struct Test {
>
> typedef UnsignedType ValueType;
> ValueType mLocalVar;
> unsigned int const mAddrLocation ;
>
> typedef std::vector < std::pair < unsigned int, unsigned int > > ADDR_VALUE_VEC ;
> static ADDR_VALUE_VEC addrValueVec ;
>
> Test ( unsigned int const addrLocation )
> : mLocalVar ( 0 )
> , mAddrLocation ( addrLocation )
> {}
>
> Test & operator= ( ValueType val )
> {
> //stuff
> return ( *this );
> }
>
> };
> typedef Test < volatile unsigned int, 32 > TestINT ;
>
> template < typename UnsignedType, unsigned Width = 0 >
> ADDR_VALUE_VEC Test < UnsignedType, Width >::addrValueVec ;
>

Read the error message, it is complaining about the second '= 0' which
is not needed (and probably not allowed even though MSVC seems to eat it).

There are other problems with this line. Welcome to the wonderful C++
template metalanguage! The correct syntax should be:

template < typename UnsignedType, unsigned Width>
typename Test<UnsignedType,Width>::ADDR_VALUE_VEC
Test < UnsignedType, Width >::addrValueVec;

What makes it so complicated is that ADDR_VALUE_VEC is defined inside a
class template Test even though it does not depend on template
parameters in any way.

HTH
Paavo

0 new messages