By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,200 Members | 1,755 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,200 IT Pros & Developers. It's quick & easy.

Problem with depracated casting method (down casting)

P: n/a
Can someone help a poor C++ programmer that learned the language before
there was a standard lib .. etc ?

Basically I have two classes that look something like below:
template <class T>
class ListLogic {
public:
struct LogicBase {
LogicBase () : next(0) { }
LogicBase* next;
};
protected:
LogicBase* head ();
};

template <class T>
class AList : private ListLogic {
protected:
struct ListNode : public ListLogic::LogicBase {
ListNode (const T& d) : data(d) { }
T data;
};
public:
......
T& head () { return ((AList<T>::ListNode*)ListLogic::head())->data; }
};

The 'AList<T>::head()' function is supposed to return the first item in the
list by taking the LogicBase pointer returned by the 'ListLogic::head()'
function and casting it a ListNode struct pointer. Then derefencing it to
retrieve the 'data' part of the ListNode struct.

On earlier versions of g++, this compiles and works fine albeit with the
following warnings:

"warning: `typename AList<T>::ListNode' is implicitly a typename"
"warning: implicit typename is deprecated"

The problem is that on newer versions of g++ the same code now is an error
with the following verbage:

"In member function 'T& AList<T>::head()':"
"error: expected primary-expression before ')' token"
"error: expected `)' before 'ListLogic'"

So it seems the old style casting used previously is no longer allowed. What
is the stardard compliant method of down casting the ListLogic::LogicBase
pointer to the AList<T>::ListNode pointer ? Thanks in advance for any
assistance.

-Wally
Nov 20 '08 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Wally Barnes wrote:
Can someone help a poor C++ programmer that learned the language before
there was a standard lib .. etc ?

Basically I have two classes that look something like below:
template <class T>
class ListLogic {
public:
struct LogicBase {
LogicBase () : next(0) { }
LogicBase* next;
};
protected:
LogicBase* head ();
};

template <class T>
class AList : private ListLogic {
template<class T>
class AList : private ListLogic<T{
protected:
struct ListNode : public ListLogic::LogicBase {
struct ListNode : public ListLogic<T>::LogicBase {
ListNode (const T& d) : data(d) { }
T data;
};
public:
......
T& head () { return ((AList<T>::ListNode*)ListLogic::head())->data; }
Maybe

T& head() {
return static_cast<
typename AList::ListNode*
>(ListLogic::head())->data;
}
};

The 'AList<T>::head()' function is supposed to return the first item in the
list by taking the LogicBase pointer returned by the 'ListLogic::head()'
function and casting it a ListNode struct pointer. Then derefencing it to
retrieve the 'data' part of the ListNode struct.

On earlier versions of g++, this compiles and works fine albeit with the
following warnings:

"warning: `typename AList<T>::ListNode' is implicitly a typename"
"warning: implicit typename is deprecated"

The problem is that on newer versions of g++ the same code now is an error
with the following verbage:

"In member function 'T& AList<T>::head()':"
"error: expected primary-expression before ')' token"
"error: expected `)' before 'ListLogic'"

So it seems the old style casting used previously is no longer allowed. What
is the stardard compliant method of down casting the ListLogic::LogicBase
pointer to the AList<T>::ListNode pointer ? Thanks in advance for any
assistance.
I believe a static_cast should do it. And in general, the 'typename' is
required, I think.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 20 '08 #2

P: n/a
Wally Barnes wrote:
>
So it seems the old style casting used previously is no longer allowed. What
is the stardard compliant method of down casting the ListLogic::LogicBase
pointer to the AList<T>::ListNode pointer ? Thanks in advance for any
assistance.
The error you are getting has absolutely noting to do with casing per
se. It is about the way you specify the name of the type. In certain
contexts type names that depend on the template parameters must be
preceded with the keyword 'typename'. Use 'typename AList<T>::ListNode*'
in you cast. However, when it comes to casting pointers along class
hierarchy, it is always better to use the new C++ casts instead of old
C-style casts. In your case that would be 'static_cast'.

--
Best regards,
Andrey Tarasevich

Nov 20 '08 #3

P: n/a
Andrey Tarasevich wrote:
Wally Barnes wrote:
>>
So it seems the old style casting used previously is no longer allowed.
What is the stardard compliant method of down casting the
ListLogic::LogicBase pointer to the AList<T>::ListNode pointer ? Thanks
in advance for any assistance.

The error you are getting has absolutely noting to do with casing per
se. It is about the way you specify the name of the type. In certain
contexts type names that depend on the template parameters must be
preceded with the keyword 'typename'. Use 'typename AList<T>::ListNode*'
in you cast. However, when it comes to casting pointers along class
hierarchy, it is always better to use the new C++ casts instead of old
C-style casts. In your case that would be 'static_cast'.
Andrey,

Thanks for the response. The issue was resolved tow different ways. The
first by inserting the 'typename' keyword inside the existing old style
cast. The other using the 'static_cast<>' new C++ standard cast. Thanks
again for the update to my outdated mental C++ database.

-Wally

Nov 20 '08 #4

P: n/a
Victor Bazarov wrote:
Wally Barnes wrote:
>Can someone help a poor C++ programmer that learned the language before
there was a standard lib .. etc ?

Basically I have two classes that look something like below:
template <class T>
class ListLogic {
public:
struct LogicBase {
LogicBase () : next(0) { }
LogicBase* next;
};
protected:
LogicBase* head ();
};

template <class T>
class AList : private ListLogic {

template<class T>
class AList : private ListLogic<T{
> protected:
struct ListNode : public ListLogic::LogicBase {

struct ListNode : public ListLogic<T>::LogicBase {
> ListNode (const T& d) : data(d) { }
T data;
};
public:
......
T& head () { return ((AList<T>::ListNode*)ListLogic::head())->data; }

Maybe

T& head() {
return static_cast<
typename AList::ListNode*
>(ListLogic::head())->data;
}
> };

The 'AList<T>::head()' function is supposed to return the first item in
the list by taking the LogicBase pointer returned by the
'ListLogic::head()' function and casting it a ListNode struct pointer.
Then derefencing it to retrieve the 'data' part of the ListNode struct.

On earlier versions of g++, this compiles and works fine albeit with the
following warnings:

"warning: `typename AList<T>::ListNode' is implicitly a typename"
"warning: implicit typename is deprecated"

The problem is that on newer versions of g++ the same code now is an
error with the following verbage:

"In member function 'T& AList<T>::head()':"
"error: expected primary-expression before ')' token"
"error: expected `)' before 'ListLogic'"

So it seems the old style casting used previously is no longer allowed.
What is the stardard compliant method of down casting the
ListLogic::LogicBase pointer to the AList<T>::ListNode pointer ? Thanks
in advance for any assistance.

I believe a static_cast should do it. And in general, the 'typename' is
required, I think.

V
Victor,

Thanks for the response. The issue was resolved tow different ways. The
first by inserting the 'typename' keyword inside the existing old style
cast. The other using the 'static_cast<>' new C++ standard cast. Thanks
again for the update to my outdated mental C++ database.

-Wally
Nov 20 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.