Confirm Template if correct

N

Nephi Immortal

Please confirm if I am correct.

If you assign “unsigned char” to typename T, then T data is
translated to unsigned char data as passing copy value.
If you assign “unsigned char &” to typename T, then T data is
translated to unsigned char &data as passing reference.

template< typename L, typename R >
class X {
public:
X< L, R >( L data ) : m_data( data ) {
}

X< L, R > &operator=( R data ) {
m_data = data;
return *this;
}

L m_data;
};

typedef unsigned char size_8;

int main () {
size_8 data = 0x34U;

const X< size_8, size_8 > A( 0x12U ); // constant
X< size_8 &, size_8 > B( data ); // reference

A.m_data++; // error cannot modify left value because of constant
class
B.m_data++; // can modify non-constant class

return 0;
}
 
V

Victor Bazarov

Please confirm if I am correct.

If you assign “unsigned char” to typename T, then T data is
translated to unsigned char data as passing copy value.
If you assign “unsigned char&” to typename T, then T data is
translated to unsigned char&data as passing reference.

First off, there is no 'T' in your code. If you're talking about a
template like this one:

template<class T> class TT { T data; };

then yes, the member 'data' has the type 'unsigned char' if you
instantiate 'TT' with 'unsigned char' and has the type 'unsigned char&'
if you instantiate 'TT' with 'unsigned char&'. Is that what you need to
confirm?
template< typename L, typename R>
class X {
public:
X< L, R>( L data ) : m_data( data ) {
}

X< L, R> &operator=( R data ) {
m_data = data;
return *this;
}

L m_data;
};

typedef unsigned char size_8;

int main () {
size_8 data = 0x34U;

const X< size_8, size_8> A( 0x12U ); // constant
X< size_8&, size_8> B( data ); // reference

A.m_data++; // error cannot modify left value because of constant
class

The 'A.m_data' has a value type. Since 'A' is const, 'A.m_data' value
is also const.
B.m_data++; // can modify non-constant class

The 'B.m_data' is a reference type (referencing a non-const object of
type 'unsigned char'. Even if you define 'B' as const, you should be
able to modify the object to which 'B.m_data' refers. Try declaring 'B'
const.
return 0;
}

V
 
N

Nephi Immortal

First off, there is no 'T' in your code.  If you're talking about a
template like this one:

    template<class T> class TT { T data; };

then yes, the member 'data' has the type 'unsigned char' if you
instantiate 'TT' with 'unsigned char' and has the type 'unsigned char&'
if you instantiate 'TT' with 'unsigned char&'.  Is that what you need to
confirm?














The 'A.m_data' has a value type.  Since 'A' is const, 'A.m_data' value
is also const.


The 'B.m_data' is a reference type (referencing a non-const object of
type 'unsigned char'.  Even if you define 'B' as const, you should be
able to modify the object to which 'B.m_data' refers.  Try declaring 'B'
const.

Yes, you are correct. I am trying to say. Can L type be replaced to
either unsigned char or unsigned char&.

For example:
template< typename L >
class X {
….
L &m_data;
}

Then, declare const as const X< unsigned char (without &) > B and
attempt to modify B.m_data should always generate an error message.

You decide to remove & from between L and m_data like below.

template< typename L >
class X {
….
L m_data;
}

and declare const X< unsigned char > A and non-const X< unsigned char
&> B.

I am surprised why C++ Compiler is able to compile without an error
message if you declare const X< unsigned char &> B. Please explain
the reason.
 
V

Victor Bazarov

Yes, you are correct. I am trying to say. Can L type be replaced to
either unsigned char or unsigned char&.

For example:
template< typename L>
class X {
….
L&m_data;
}

Then, declare const as const X< unsigned char (without&)> B and
attempt to modify B.m_data should always generate an error message.

You decide to remove& from between L and m_data like below.

template< typename L>
class X {
….
L m_data;
}

and declare const X< unsigned char> A and non-const X< unsigned char
&> B.

I am surprised why C++ Compiler is able to compile without an error
message if you declare const X< unsigned char&> B. Please explain
the reason.

I thought I did. The part of the constant object X<uc&> (the reference)
is constant, but the object it refers to (the actual unsigned char) is
not. I am not sure how to explain it to you better. Maybe this example
(quiz) is going to help:

#include <iostream>

struct A {
void foo() const { std::cout << "const foo\n"; }
void foo() { std::cout << "regular foo\n"; }
}

struct B {
A* pA;
};

int main() {
A a; // non-const object of type A
a.foo(); // expect "regular foo"
B b = { &a }; // non-const B
b.pA->foo(); // expect "regular foo"
B const bc = { &a };
bc.pA->foo(); // which one should you expect?
}

Try to answer the last question without running the program and explain
your reasoning.

V
 
I

itaj sherman

I am surprised why C++ Compiler is able to compile without an error
message if you declare const X< unsigned char &> B. Please explain
the reason.- Hide quoted text -

Consider that a reference to T is equivalent to a const pointer to T
(non-null)
T& eqv T* const

Non-null const pointer has the same semantic as references, just
different syntax.

If you refrase you question using pointer syntax, would you still be
surprised?
If T is non-const, you change it through any pointer to T, even a
const pointer to T.

typedef unsigned char size_8;

int main () {
size_8 data = 0x34U;


const X< size_8, size_8 > A( 0x12U );
X< size_8* const, size_8 > B( &data ); //


A.m_data++;
(*(B.m_data))++; // B.m_data is a const pointer to non-const
size_8


return 0;
}

itaj
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top