why I need explicit static_cast to const reference

G

Grizlyk

I found, that I must write explicit cast from non-const reference to const
reference.

I have a class with member returning non-const reference to itself

template<class A,class B,class C>
class X
{
public:
X& my_member(){return *this;}
};


And I have a class working with const reference on X<>

template<class A,class B,class C>
class Y
{
public:
typedef X<A,B,C> X;

void work(const X&, const X&);
};

And I have a class with typedefs

template<class A,class B,class C>
class Z
{
public:
typedef X<A,B,C> X;
typedef Y<A,B,C> Y;
};


When i try to use the classes together

{
Z::X x1,x2;
Z::Y y;

//error - does not match y.work
y.work( x1.my_member(), x2.my_member() );

//ok
y.work(
static_cast<const Z::X&>(x1.my_member()),
static_cast<const Z::X&>(x2.my_member())
);

//ok
y.work( x1, x2 );

}


Why "error - does not match y.work"?
 
K

Kai-Uwe Bux

Grizlyk said:
I found, that I must write explicit cast from non-const reference to const
reference.

I have a class with member returning non-const reference to itself

template<class A,class B,class C>
class X
{
public:
X& my_member(){return *this;}
};


And I have a class working with const reference on X<>

template<class A,class B,class C>
class Y
{
public:
typedef X<A,B,C> X;

void work(const X&, const X&);
};

And I have a class with typedefs

template<class A,class B,class C>
class Z
{
public:
typedef X<A,B,C> X;
typedef Y<A,B,C> Y;
};


When i try to use the classes together

{
Z::X x1,x2;
Z::Y y;

//error - does not match y.work
y.work( x1.my_member(), x2.my_member() );

//ok
y.work(
static_cast<const Z::X&>(x1.my_member()),
static_cast<const Z::X&>(x2.my_member())
);

//ok
y.work( x1, x2 );

}


Why "error - does not match y.work"?

I tried to put the pieces you posted together to reproduce the error. But I
failed; the following compiles fine on my machine:


template<class A,class B,class C>
class X
{
public:
X& my_member(){return *this;}
};
template<class A,class B,class C>
class Y
{
public:
typedef X<A,B,C> X;

void work(const X&, const X&);
};
template<class A,class B,class C>
class Z
{
public:
typedef X<A,B,C> X;
typedef Y<A,B,C> Y;

void dummy () {
X x1,x2;
Y y;

y.work( x1.my_member(), x2.my_member() );

}

};

int main ( void ) {}


Could you provide a small complete program that shows the error?


Best

Kai-Uwe Bux
 
G

Gianni Mariani

Grizlyk said:
I found, that I must write explicit cast from non-const reference to const
reference.
.... snipped

Why "error - does not match y.work"?

Works for me. It might be your compiler.

BTW - next time, make it so I can just cun-n-paste and compile - like SO:


template<class A,class B,class C>
class X
{
public:
X& my_member(){return *this;}
};


// And I have a class working with const reference on X<>

template<class A,class B,class C>
class Y
{
public:
typedef X<A,B,C> X;

void work(const X&, const X&) {}
};

// And I have a class with typedefs

template<class A,class B,class C>
class Z
{
public:
typedef X<A,B,C> X;
typedef Y<A,B,C> Y;
};


// When i try to use the classes together

int main()
{
typedef Z<int,int,int> Z;
Z::X x1,x2;
Z::Y y;

//error - does not match y.work
y.work( x1.my_member(), x2.my_member() );

//ok
y.work(
static_cast<const Z::X&>(x1.my_member()),
static_cast<const Z::X&>(x2.my_member())
);

//ok
y.work( x1, x2 );

}
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

I found, that I must write explicit cast from non-const reference to const
reference.

I have a class with member returning non-const reference to itself

template<class A,class B,class C>
class X
{
public:
X& my_member(){return *this;}

};

For some functions/operators it can be a good idea to declare a const-
version:

const X& my_member() const { return *this; }

Whenever you have a const instance of X and call my_member() on it
it's the const-version that will be called.
 
G

Grizlyk

Grizlyk said:
I found, that I must write explicit cast from non-const reference to const
reference.

y.work(
static_cast<const Z::X&>(x1.my_member()),
static_cast<const Z::X&>(x2.my_member())
);

I was wrong, the cause of neccessary static_cast is inheritance. Insead of
template<class A,class B,class C>
class X
{
public:
X& my_member(){return *this;}
};

I really have in "my_member()" reference to X<A,B,C> base class returned:

template<class A,class B,class C>
class X: public Base<A,B,C>
{
public:
Base<A,B,C>& my_member(){return *this;}
};

So i get unexpected example of CRTP implementation - static_cast to derived
class.
 
G

Grizlyk

Grizlyk said:
So i get unexpected example of CRTP implementation - static_cast to
derived class.


And I have divided classes like this

template<class A,class B,class C>
class Base<A,B,C>
{
public:
Base<A,B,C>& my_member(){return *this;}
};


template<class A,class B,class C>
class X: public Base<A,B,C>
{
public:
X& my_member(){return static_cast<X&>(Base<A,B,C>::my_member());}
};
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top