How to make a "long&" parameter optional

O

Otto Wyss

I've the following function declaration:

wxTree GetLastChild (const wxTree& item, long& cookie) const;

I'd like to make the cookie parameter optional, i.e. "long& cookie =
....", without breaking any software using the old API. The
implementation looks like

wxTree wxTreeListMainWindow::GetLastChild (const wxTree& item,
long& cookie) const {
wxCHECK_MSG (item.IsOk(), wxTree(), wxT("invalid tree item"));
wxArrayTreeListItems& children = ((wxTreeListItem*)
item.m_pItem)->GetChildren();
// it's ok to cast cookie to long, indices won't overflow "void*"
long *pIndex = ((long*)&cookie);
(*pIndex) = children.Count();
return (!children.IsEmpty())? wxTree(children.Last()): wxTree();
}

BTW the cast is not from me! Is this optional parameter possible? If not
what alternatives are there?

Full source:
"http://cvs.sourceforge.net/viewcvs.py/wxcode/wxCode/components/treelist
ctrl/src/treelistctrl.cpp?view=markup"

O. Wyss
 
G

Gianni Mariani

Otto Wyss wrote:
....
BTW the cast is not from me! Is this optional parameter possible? If not
what alternatives are there?

optional reference parameter example.

static long g__foo; // you can make an extern if you wish ..

void Func( long & x = g__foo );
 
R

Ron Natalie

Otto said:
I've the following function declaration:

wxTree GetLastChild (const wxTree& item, long& cookie) const;

I'd like to make the cookie parameter optional, i.e. "long& cookie =
...", without breaking any software using the old API. The
implementation looks like

class wxTreeListMainWindow {
....
static long dummy;
wxTree GetLastChild(const WxTree& item, long& cookie = wxTreeListMainWindow::dummy)const;
 
V

Victor Bazarov

Otto said:
I've the following function declaration:

wxTree GetLastChild (const wxTree& item, long& cookie) const;

I'd like to make the cookie parameter optional, i.e. "long& cookie =
...", without breaking any software using the old API. The
implementation looks like

wxTree wxTreeListMainWindow::GetLastChild (const wxTree& item,
long& cookie) const {
wxCHECK_MSG (item.IsOk(), wxTree(), wxT("invalid tree item"));
wxArrayTreeListItems& children = ((wxTreeListItem*)
item.m_pItem)->GetChildren();
// it's ok to cast cookie to long, indices won't overflow "void*"
long *pIndex = ((long*)&cookie);
(*pIndex) = children.Count();
return (!children.IsEmpty())? wxTree(children.Last()): wxTree();
}

BTW the cast is not from me! Is this optional parameter possible? If not
what alternatives are there?

If you mean, some kind of "default argument value"? The problem with this
is that your reference is to a non-const long object. So, it has to refer
to (a) something valid, no 'null' references exist, and (b) be a reference
to an l-value. The only way to do that, AFAIK, is to provide your own
object and inside compare the address:

-------------------------------------- in the header
extern long default_cookie;
...
class wxTreeListMainWindow {
...
wxTree GetLastChild(const wxTree& item,
long& cookie = default_cookie);
...
};
--------------------------------------- in the C++ file
...
extern long default_cookie = 0; // definition!!!
...
wxTree wxTreeListMainWindow::GetLastChild (const wxTree& item,
long& cookie) const {
...
if (&cookie == &default_cookie) {
// default
}
...
}
 
O

Otto Wyss

Victor Bazarov said:
If you mean, some kind of "default argument value"? The problem with this
is that your reference is to a non-const long object. So, it has to refer
to (a) something valid, no 'null' references exist, and (b) be a reference
to an l-value. The only way to do that, AFAIK, is to provide your own
object and inside compare the address:

-------------------------------------- in the header
extern long default_cookie;

I feared there might not be a nice solution, I don't like to declare a
dummy object. I've considered to write wrapper functions but that
doesn't appeal to me either. So what would be the best solution if I
drop the "without breaking any software using the old API"?

Full source:
"http://cvs.sourceforge.net/viewcvs.py/wxcode/wxCode/components/treelist
ctrl/src/treelistctrl.cpp?view=markup"

O. Wyss
 
V

Victor Bazarov

Otto said:
I feared there might not be a nice solution, I don't like to declare a
dummy object. I've considered to write wrapper functions but that
doesn't appeal to me either. So what would be the best solution if I
drop the "without breaking any software using the old API"?

Make it a pointer and have a null pointer indicate "optionality".
That's a very common solution.

V
 
J

Jeff Flinn

Otto Wyss said:
I feared there might not be a nice solution, I don't like to declare a
dummy object. I've considered to write wrapper functions but that
doesn't appeal to me either. So what would be the best solution if I
drop the "without breaking any software using the old API"?

The simple answer is an overload of GetLastChild without the long&
parameter.

wxTree wxTreeListMainWindow::GetLastChild (const wxTree& item )const
{
wxCHECK_MSG (item.IsOk(), wxTree(), wxT("invalid tree item"));

wxArrayTreeListItems& children =
((wxTreeListItem*)item.m_pItem)->GetChildren();

return (!children.IsEmpty())? wxTree(children.Last()): wxTree();
}

I favor a more functional approach, avoiding out parameters, by having
GetlastChild return a std::pair<wxTree,long>. Then client can then ignore
the long value:

std::pair<wxTree,long> wxTreeListMainWindow::GetLastChild( const wxTree&
item )const
{
wxCHECK_MSG (item.IsOk(), wxTree(), wxT("invalid tree item"));

wxArrayTreeListItems& children =
((wxTreeListItem*)item.m_pItem)->GetChildren();

return std::make_pair( (!children.IsEmpty())? wxTree(children.Last()):
wxTree()
, children.Count()
);
}

Jeff F
 

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,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top