473,507 Members | 2,477 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Inheritance of overloaded vararg methods

Hello,

I've been banging my head against this problem for a couple hours now
to no avail.
I'm trying to make a descendant of a class that has overloaded methods
with variable argument lists. The problem is, when my descendant class
does the same, function resolution seems to stop there without looking
at the base class.

This happens both with g++ and VS2005, so I don't suspect it's a
compiler bug.

Note that I'm just trying to inherit these methods (which are
overloaded on name), not override their implementation.

Here's a trivial example:

/////~ begin code ~/////
class T1 {};
class T2 {};

class A
{
public:
int Get(T1&, char const*, ...);
int Get(double&, char const*, ...);
};

class B : public A
{
public:
int Get(T2&, char const*, ...);
int Get(int&, char const*, ...);
};

int main(int argc, char** argv)
{
B b;
T1 t1;
// Would expect it to call A::Get(T1&, char const*, ...);
// but it doesn't; it errors out saying that B::(T2&, char
const*, ...)
// can't cast the first operator.
return b.Get(t1, "Foo", 15);
}
/////~ end code ~/////

The actual error message g++ puts out is:
vatest.cpp: In function `int main(int, char**)':
vatest.cpp:25: error: no matching function for call to `B::Get(T1&,
const char[5])'
vatest.cpp:14: note: candidates are: int B::Get(T2&, const char*, ...)
vatest.cpp:15: note: int B::Get(int&, const char*, ...)

This seems pretty puzzling to me -- it doesn't even look at the
methods A provides!
If I declare all of A's methods in B (e.g., if I were to make them
virtual and provide my own implementations in every overriding class),
resolution works just fine; but then I'm left with the problem of
implementing them all by manually passing a va_list to the
base...something that seems very hacky and dangerous.

Can anyone shed some light on this?

Thanks,
Robert Estelle
Dec 15 '07 #1
6 2242
On 2007-12-15 01:56:47 -0500, Ro***********@gmail.com said:
>>
>>The actual error message g++ puts out is:
vatest.cpp: In function `int main(int, char**)':
vatest.cpp:25: error: no matching function for call to `B::Get(T1&,
const char[5])'
vatest.cpp:14: note: candidates are: int B::Get(T2&, const char*, ...)
vatest.cpp:15: note: int B::Get(int&, const char*, ...)
>>This seems pretty puzzling to me -- it doesn't even look at the
methods A provides!

Thanks for the link.
The solution is to put 'using A::Get;' in B's class declaration.

As an aside - had I gotten any such warning as the FAQ mentions
("Warning: Derived::f(char) hides Base::f(double)"), I would have come
across it in my searching; the problem was, I got no warning from
either VS2005 or gcc with -Wall, only the compile error I included in
my post.
Right. Compilers are professional tools, not tutorials. You got the
problem exactly right: the compiler doesn't look at the member
functions that A provides. You didn't know why that was the case. Now
you do, and you'll know how to interpret similar error messages in the
future, without needing lengthy explanations from the compiler.

And note that a little experimentation would have shown that the
variable-length argument lists aren't part of the problem.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Dec 15 '07 #2
On Dec 15, 8:53 am, RobertEste...@gmail.com wrote:
/////~ begin code ~/////
class T1 {};
class T2 {};

class A
{
public:
int Get(T1&, char const*, ...);
int Get(double&, char const*, ...);

};

class B : public A
{
public:
int Get(T2&, char const*, ...);
int Get(int&, char const*, ...);

};

int main(int argc, char** argv)
{
B b;
T1 t1;
// Would expect it to call A::Get(T1&, char const*, ...);
// but it doesn't; it errors out saying that B::(T2&, char
const*, ...)
// can't cast the first operator.
return b.Get(t1, "Foo", 15);}

/////~ end code ~/////

The actual error message g++ puts out is:
vatest.cpp: In function `int main(int, char**)':
vatest.cpp:25: error: no matching function for call to `B::Get(T1&,
const char[5])'
vatest.cpp:14: note: candidates are: int B::Get(T2&, const char*, ...)
vatest.cpp:15: note: int B::Get(int&, const char*, ...)
Are reference arguments, okay? Isn't it UB? Because, I couldn't find
anything about it in the C++ standards and C does not know about
references.
Dec 15 '07 #3
On Dec 15, 3:35 pm, Abhishek Padmanabh <abhishek.padman...@gmail.com>
wrote:
On Dec 15, 8:53 am, RobertEste...@gmail.com wrote:
/////~ begin code ~/////
class T1 {};
class T2 {};
class A
{
public:
int Get(T1&, char const*, ...);
int Get(double&, char const*, ...);
};
class B : public A
{
public:
int Get(T2&, char const*, ...);
int Get(int&, char const*, ...);
};
int main(int argc, char** argv)
{
B b;
T1 t1;
// Would expect it to call A::Get(T1&, char const*, ...);
// but it doesn't; it errors out saying that B::(T2&, char
const*, ...)
// can't cast the first operator.
return b.Get(t1, "Foo", 15);}
/////~ end code ~/////
The actual error message g++ puts out is:
vatest.cpp: In function `int main(int, char**)':
vatest.cpp:25: error: no matching function for call to `B::Get(T1&,
const char[5])'
vatest.cpp:14: note: candidates are: int B::Get(T2&, const char*, ...)
vatest.cpp:15: note: int B::Get(int&, const char*, ...)
Are reference arguments okay? Isn't it UB? Because, I couldn't
find anything about it in the C++ standards and C does not
know about references.
Anything about what? §8.3.5 definitely talks about the
ellipsis, saying that it can terminate the function parameter
list. And it doesn't say anything about it introducing
additional restrictions on the previous arguments, so it
doesn't.

There is a restriction on the right most argument (parmN) if
you use va_start (§18.8/3): "If the parameter parmN is declared
with a function, array, or reference type, or with a type that
is not compatible with the type that results when passing an
argument for which there is no parameter, the behavior is
undefined." This can't affect his code, however, since the
right most argument has type char const*.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 15 '07 #4
On Dec 15, 10:59 pm, James Kanze <james.ka...@gmail.comwrote:
On Dec 15, 3:35 pm, Abhishek Padmanabh <abhishek.padman...@gmail.com>
wrote:
On Dec 15, 8:53 am, RobertEste...@gmail.com wrote:
/////~ begin code ~/////
class T1 {};
class T2 {};
class A
{
public:
int Get(T1&, char const*, ...);
int Get(double&, char const*, ...);
};
class B : public A
{
public:
int Get(T2&, char const*, ...);
int Get(int&, char const*, ...);
};
int main(int argc, char** argv)
{
B b;
T1 t1;
// Would expect it to call A::Get(T1&, char const*, ...);
// but it doesn't; it errors out saying that B::(T2&, char
const*, ...)
// can't cast the first operator.
return b.Get(t1, "Foo", 15);}
/////~ end code ~/////
The actual error message g++ puts out is:
vatest.cpp: In function `int main(int, char**)':
vatest.cpp:25: error: no matching function for call to `B::Get(T1&,
const char[5])'
vatest.cpp:14: note: candidates are: int B::Get(T2&, const char*, ...)
vatest.cpp:15: note: int B::Get(int&, const char*, ...)
Are reference arguments okay? Isn't it UB? Because, I couldn't
find anything about it in the C++ standards and C does not
know about references.

Anything about what? §8.3.5 definitely talks about the
ellipsis, saying that it can terminate the function parameter
list. And it doesn't say anything about it introducing
additional restrictions on the previous arguments, so it
doesn't.

There is a restriction on the right most argument (parmN) if
you use va_start (§18.8/3): "If the parameter parmN is declared
with a function, array, or reference type, or with a type that
is not compatible with the type that results when passing an
argument for which there is no parameter, the behavior is
undefined." This can't affect his code, however, since the
right most argument has type char const*.
Yes, I was not clear about restrictions on previous arguments. So, I
believe, reference arguments to vararg functions are fine if they are
not the right most argument before (...). Thanks!
Dec 16 '07 #5
On Dec 16, 5:34 am, Abhishek Padmanabh <abhishek.padman...@gmail.com>
wrote:
On Dec 15, 10:59 pm, James Kanze <james.ka...@gmail.comwrote:
[...]
There is a restriction on the right most argument (parmN) if
you use va_start (§18.8/3): "If the parameter parmN is declared
with a function, array, or reference type, or with a type that
is not compatible with the type that results when passing an
argument for which there is no parameter, the behavior is
undefined." This can't affect his code, however, since the
right most argument has type char const*.
Yes, I was not clear about restrictions on previous arguments. So, I
believe, reference arguments to vararg functions are fine if they are
not the right most argument before (...). Thanks!
They're also fine if you don't use va_start in the function.
Not very useful, of course, but legal:-).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Dec 16 '07 #6
On Dec 15, 5:55 am, Pete Becker <p...@versatilecoding.comwrote:
On 2007-12-15 01:56:47 -0500, RobertEste...@gmail.com said:


>The actual error message g++ puts out is:
vatest.cpp: In function `int main(int, char**)':
vatest.cpp:25: error: no matching function for call to `B::Get(T1&,
const char[5])'
vatest.cpp:14: note: candidates are: int B::Get(T2&, const char*, ...)
vatest.cpp:15: note: int B::Get(int&, const char*, ...)
>This seems pretty puzzling to me -- it doesn't even look at the
methods A provides!
Thanks for the link.
The solution is to put 'using A::Get;' in B's class declaration.
As an aside - had I gotten any such warning as the FAQ mentions
("Warning: Derived::f(char) hides Base::f(double)"), I would have come
across it in my searching; the problem was, I got no warning from
either VS2005 or gcc with -Wall, only the compile error I included in
my post.

Right. Compilers are professional tools, not tutorials. You got the
problem exactly right: the compiler doesn't look at the member
functions that A provides. You didn't know why that was the case. Now
you do, and you'll know how to interpret similar error messages in the
future, without needing lengthy explanations from the compiler.

And note that a little experimentation would have shown that the
variable-length argument lists aren't part of the problem.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)
Quite right - I realized that I should have narrowed the test down to
see if the varargs actually had anything to do with it, soon after
posting. Once I got back to a computer, Alf had already found the
solution.
Dec 17 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
10028
by: km | last post by:
Hi all, In the following code why am i not able to access class A's object attribute - 'a' ? I wishto extent class D with all the attributes of its base classes. how do i do that ? thanks in...
14
12878
by: Steve Jorgensen | last post by:
Recently, I tried and did a poor job explaining an idea I've had for handling a particular case of implementation inheritance that would be easy and obvious in a fully OOP language, but is not at...
45
6309
by: Ben Blank | last post by:
I'm writing a family of classes which all inherit most of their methods and code (including constructors) from a single base class. When attempting to instance one of the derived classes using...
6
3272
by: apm | last post by:
Recently I have had to use a value type for a complex structure because I don't know how to override the = operator. Can the operator ever be overloaded? Or can inheritance be used with value types?
8
1253
by: query_me2001 | last post by:
I have a queue that holds a list of objects with a common base type. As a simple and contrived example, I have a common type of transportation methods and derived classes (with there own individual...
10
3349
by: Mihai Osian | last post by:
Hi everyone, Given the code below, can anyone tell me: a) Is this normal behaviour ? b) If it is, what is the reason behind it ? I would expect the A::method(int) to be inherited by B. ...
64
3398
by: groups | last post by:
C# is an impressive language...but it seems to have one big limitation that, from a C++ background, seems unacceptable. Here's the problem: I have a third-party Document class. (This means I...
5
1868
by: Lars Hillebrand | last post by:
Hello, i discovered a weird behaviour if i use templates together with virtual inheritance and method over. I managed to reproduce my problem with a small example: // *********** <code...
3
3873
by: puzzlecracker | last post by:
Are static method inheritable under csharp rules, if so how can they be used? Can they be virtual? They reason I am asking is because operators are static, and I don't understand how can we...
0
7114
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7321
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7377
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7034
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5623
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5045
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3191
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
1
762
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
412
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.