473,416 Members | 1,714 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,416 software developers and data experts.

namespaces and function overloading

Hi all,

I have the following code:

namespace A {
inline void func(int) { ...; }
inline void func(float) { ...; }
inline void func(char) { ...; }
}

namespace B {
inline void func(double) { ...; }

inline myApp()
{
int a;
func(a); // error here
}
}

Which results in the compile-error:
"cannot convert parameter 1 from 'int' to 'double' ...

Which I guess means that all the definitions of func in namespace A are
forgotten in namespace B. Is this something general for c++ or is it
specific for my microsoft visual c++ 6.0 . And more importantly, is there a
work-around / solution ?
thanks ahead,
Richard
Jul 23 '05 #1
12 2947
RA Scheltema wrote:

Hi all,

I have the following code:

namespace A {
inline void func(int) { ...; }
inline void func(float) { ...; }
inline void func(char) { ...; }
}

namespace B {
inline void func(double) { ...; }

inline myApp()
{
int a;
func(a); // error here
}
}

Which results in the compile-error:
"cannot convert parameter 1 from 'int' to 'double' ...
Hmm. I don't get this error when compiling the above. And I
use VC++ 6.0

Which I guess means that all the definitions of func in namespace A are
forgotten in namespace B.


No, they are not forgotten. But namespace A is not searched for the
functions

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #2
> Hmm. I don't get this error when compiling the above. And I
use VC++ 6.0
Hmm, in my project its part of quite a large code-base. Maybe I should have
checked the code :(, however the example is a very stripped down version of
my problem.
No, they are not forgotten. But namespace A is not searched for the
functions


But this means that when a function "func" is found in namespace B it will
only try this one and don't bother with the ones in namespace A ? This would
concur with what I'm finding in my project, since the error does not occur
when I don't define a function "func" in namespace B (in my project that is
....).

I did find the following solution:

using A::func;
namespace B{
....
}
however this results in the error:
"ambiguous call to func ..."

and explicit casting does not solve the problem.
Is there something I'm doing wrong ?
regards,
Richard
Jul 23 '05 #3
>> Hmm. I don't get this error when ?
compiling the above. And I
use VC++ 6.0
Hmm, in my project its part of quite a
large code-base. Maybe I should have
checked the code :(, however the example
is a very stripped down version of
my problem.
What Karl meant is that conversion from int
to double is legal and you shouldn't have
had an error about it. It may be that your
error was different on the real code, I
think we all understand what you mean.
No, they are not forgotten. But namespace
A is not searched for the functions But this means that when a function
"func" is found in namespace B it will
only try this one and don't bother with
the ones in namespace A ? This would
concur with what I'm finding in my
project, since the error does not occur
when I don't define a function "func" in
namespace B (in my project that is
...).
This:

namespace A
{
void f();
}

namespace B
{
void g()
{
f(); // error
}
}

is invalid. Namespaces are meant to
prevent name clashing and therefore, it is
by design that function in a namespace are
not available from another, without special
syntax.
I did find the following solution: using A::func;
namespace B{
...

}
This is one way of doing it.
however this results in the error:
"ambiguous call to func ..."
Where? If it's at namespace scope, this is
weird because in a namespace, local names
will always be preferred to other names.
Therefore, this is valid:

namespace A
{
void f(int) {}
}

using namespace A;
namespace B
{
void f(int) {}

void g()
{
f(10); // ok, calls B::f()
}
}

The problem is in the global scope:

int main()
{
using namespace A;
using namespace B;

f(10); // ambiguous
}
and explicit casting does not solve the
problem.
What casting?
Is there something I'm doing wrong ?


You don't understand namespaces. Read
about them.
Jonathan

Jul 23 '05 #4

"Jonathan Mcdougall"
Where? If it's at namespace scope, this is
weird because in a namespace, local names
will always be preferred to other names.


I find with BCB6 that A::func(double) is called with this test:
namespace A {
inline void func(int) { ; }
inline void func(float) { ; }
inline void func(char) { ; }
inline void func(double) { ; }
}

namespace B {
inline void func(double) { ; }

inline void myApp()
{
using A::func;
//using B::func;
double a;
func(a); // error here
}
}

#pragma argsused
int main(int argc, char* argv[])
{ B::myApp();
return 0;
}
Jul 23 '05 #5
>> Where? If it's at namespace scope, this is
weird because in a namespace, local names
will always be preferred to other names.
I find with BCB6 that A::func(double) is called with this test:


That's not the same thing.
namespace A {
inline void func(int) { ; }
inline void func(float) { ; }
inline void func(char) { ; }
inline void func(double) { ; }
}

namespace B {
inline void func(double) { ; }

inline void myApp()
{
using A::func;
//using B::func;
double a;
func(a); // error here
This should prefer A::func to B::func because you specificaly say it
with 'using A::func'. You should have no error because there is no
ambiguity.

namespace A
{
void f(int);
}

namespace B
{
void f(int);

void g()
{
f(10); // calls B::f

using namespace A;
f(10); // calls B::f (preferred over A::f)

using A::f;
f(10); // calls A::f (because of using)
}
}

int main()
{
f(10); // error, not found

// dump both namespaces here
using namespace A;
using namespace B;

// ambiguous (using both A::f and B::f)
f(10);

// specifically use A::f
using A::f;

// calls A::f
f(10);

// specifically use B::f (this does *not* override
// the previous using declaration)
using B::f;

// ambiguous (using both A::f and B::f)
f(10);
}
}

}

#pragma argsused
Make sure you strip non standard code before posting.
int main(int argc, char* argv[])
{ B::myApp();
return 0;
}


--
Jonathan
[comp.lang.c++ FAQ] - http://www.parashift.com/c++-faq-lite/

Jul 23 '05 #6
If I want to prefer a swap function written for a class in its namespace
over std:swap I thought I should have a using declaration for std:swap
before the call. So that won't work as I expected.

Fraser.
Jul 23 '05 #7
Instead of a using declaration I want a using directive with minimal code
blocked. I.E:
{
using namespace std;
swap(a1,a2);
}
Argument dependent lookup will link the call to any swap function in the
namespace of the type of a1/a2.

Fraser.

If I want to prefer a swap function written for a class in its namespace
over std:swap I thought I should have a using declaration for std:swap
before the call. So that won't work as I expected.

Fraser.

Jul 23 '05 #8
> If I want to prefer a swap function
written for a class in its namespace
over std:swap
You should have no problem if no
using directive is used:

# include <algorithm>

namespace N
{
class A {};
void swap(const A &a, const A &b);
}

int main()
{
N::A a, b;
swap(a, b); // A::swap()
}

Since ADL is used as a "last resort",
the compiler will use another swap
function if it can be found (such as
with a using directive/declaration or
with a global swap function).

Be careful though: Microsoft Visual
C++ 7.0 does not handle ADL
correctly since it ignores it for
ordinary functions (as opposed to
operators). Therefore, the above
example does not compile. I do not know
for Visual C++ 7.1.
I thought I should have a using
declaration for std:swap before
the call. So that won't work as I
expected.


I don't understand that.

Maybe if you provided some actual
code we could help you more with
your problem than with theoritical
solutions.

Jonathan

Jul 23 '05 #9

"Jonathan Mcdougall"
If I want to prefer a swap function
written for a class in its namespace
over std:swap
You should have no problem if no
using directive is used:

# include <algorithm>

namespace N
{
class A {};
void swap(const A &a, const A &b);
}

int main()
{
N::A a, b;
swap(a, b); // A::swap()


Don't you mean N::swap()?

}

Since ADL is used as a "last resort",
the compiler will use another swap
function if it can be found (such as
with a using directive/declaration or
with a global swap function).


You said in the comment N::swap will be called. My compiler chooses
N::swap. It is the behaviour I want. I'd like to know where in the
standard is the rule for this.

In general ADL is not any kind of last resort. It leads to ambiguity.

Fraser.
Jul 23 '05 #10

"Fraser Ross"

"Jonathan Mcdougall"
If I want to prefer a swap function
written for a class in its namespace
over std:swap


You should have no problem if no
using directive is used:

# include <algorithm>

namespace N
{
class A {};
void swap(const A &a, const A &b);
}

int main()
{
N::A a, b;
swap(a, b); // A::swap()


Don't you mean N::swap()?

}

Since ADL is used as a "last resort",
the compiler will use another swap
function if it can be found (such as
with a using directive/declaration or
with a global swap function).


You said in the comment N::swap will be called. My compiler chooses
N::swap. It is the behaviour I want. I'd like to know where in the
standard is the rule for this.


N::swap is called because of the rule, prefer nontemplates. Incidentally
the constness is wrong with the parameters.

If N::swap is a template there is ambiguity. Probably I would write a
nontemplate N::swap specifically for parameters of A&. Using:
{
using namespace std;
swap(a1,a2);
}
is rather a lot of code so I am in favour of the STL container way of doing
swap now. That is put a partial specialisation of swap in namespace std
which calls a member function called swap of the class.

I wish I could remember where in Effective STL it says something about
whether a program is allowed to add to STL.

Fraser.
Jul 23 '05 #11
>>>> # include <algorithm>

namespace N
{
class A {};
void swap(const A &a, const A &b);
}

int main()
{
N::A a, b;
swap(a, b); // A::swap()

Don't you mean N::swap()?
Yes I do.
}

Since ADL is used as a "last resort",
the compiler will use another swap
function if it can be found (such as
with a using directive/declaration or
with a global swap function).
You said in the comment N::swap will be called.
My compiler chooses N::swap.

Good.
It is the behaviour I
want. I'd like to know where in the standard is
the rule for this.
3.4.2 in the 1996 working draft.

"When an unqualified name is used as the
postfix-expression in a function call (_expr.call_),
other namespaces not considered during the usual
unqualified look up (_basic.lookup.unqual_) may be
searched; this search depends on the types of the
arguments."
In general ADL is not any kind of last resort.
It leads to ambiguity.


Umm... no. Without adl, this

# include <iostream>

int main()
{
std::cout << "hello";
}

would not work.
N::swap is called because of the rule, prefer
nontemplates.
In my example, no. It's because there is *no*
other swap function declared in this scope.
Incidentally the constness is wrong
with the parameters.
What? Passing a non-const to a const is quite
correct imo.
If N::swap is a template there is ambiguity.
With which one?
Probably I would write a nontemplate N::swap
specifically for parameters of A&. Using:

{
using namespace std;
swap(a1,a2);
}

is rather a lot of code so I am in favour of the
STL container way of doing swap now. That is put
a partial specialisation of swap in namespace std
which calls a member function called swap of the
class.
You may do that.
I wish I could remember where in Effective STL it
says something about whether a program is
allowed to add to STL.


17.3.3.1 in the 1996 draft.

"1 It is undefined for a C++ program to add
declarations or definitions to namespace std or
namespaces within namespace std unless otherwise
specified. A program may add template specializations
for any standard library template to namespace
std. Such a specialization (complete or partial) of
a standard library template results in undefined
behaviour unless the declaration depends on a
user-defined name of external linkage and unless
the specialization meets the standard library
requirements for the original template.20)"

By the way, try to post one message at a time.

--
Jonathan
[FAQ] - http://www.parashift.com/c++-faq-lite/

Jul 23 '05 #12

"Jonathan Mcdougall"
It is the behaviour I
want. I'd like to know where in the standard is
the rule for this.
3.4.2 in the 1996 working draft.

"When an unqualified name is used as the
postfix-expression in a function call (_expr.call_),
other namespaces not considered during the usual
unqualified look up (_basic.lookup.unqual_) may be
searched; this search depends on the types of the
arguments."
Thats not the reason. I have already given it in my later post: N::swap is
called because of the rule, prefer nontemplates. Actually I did not notice
that there is not a using directive but it would not matter.

In general ADL is not any kind of last resort.
It leads to ambiguity.


Umm... no. Without adl, this

# include <iostream>

int main()
{
std::cout << "hello";
}

would not work.


I know its used there. You said that functions found with ADL are not
prefered to any found with a using directive but they result in ambiguity.
A global function is in the almost immediate scope so its prefered and a
function named with a using declaration is prefered over that.

Fraser.


Jul 23 '05 #13

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

Similar topics

2
by: Frederick Reeve | last post by:
Hey all I have a little compilation problem I think is related to name spaces but being new to C++ still I don't know the program (http://rafb.net/paste/results/f1416037.html) when it is being...
6
by: BigMan | last post by:
I've come to the decision to use multiple namespaces for a very specific reason: I like to use descriptive names of UDTs and I sometimes come up with long UDT names (and file names too, since I...
1
by: Talin | last post by:
Thanks to everyone for pointing out my bone-headed errors :) I don't *usually* make that sort of mistake... What I'm attempting to do is create an implentation of the unification algorithm. Now,...
39
by: zeus | last post by:
I know function overloading is not supported in C. I have a few questions about this: 1. Why? is it from technical reasons? if so, which? 2. why wasn't it introduced to the ANSI? 3. Is there any...
45
by: JaSeong Ju | last post by:
I would like to overload a C function. Is there any easy way to do this?
2
by: Beeeeeeeeeeeeves | last post by:
Does C# really HAVE to have namespaces? Isn't there any way I can turn them off? I did a bit of dabbling in VB.NET but have decided not to switch to it permanantly as I've got too much pre-written...
11
by: Random | last post by:
I'm confused about the proper use and usefulness of namespaces. I beleive I understand the purpose is so the developer can put classes within namespaces to essentially organize your code. And I...
1
by: thetrueaplus | last post by:
Hey all. I posted this originally: http://groups.google.com/group/comp.lang.c++/browse_thread/thread/b1e4b76201ce17f1 I got the enums to work how I like but I am having a problem with the...
11
by: jakester | last post by:
I am using Visual C++ 2007 to build the code below. I keep getting linkage error. Could someone please tell me what I am doing wrong? The code works until I start using namespace for my objects. ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
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,...
0
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...

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.