469,568 Members | 1,520 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,568 developers. It's quick & easy.

Overriding stl::sort()

The stl::sort() that comes with Dev Studio 6 is broken (it hits the
degenerate case in a common situation). I have a replacement.
I would like to globally do "using namespace std; except use my
sort()".

I'd heard you can do this within a namespace:

namespace Fixed
{
using namespace std;
using Replacement::sort();
}
using namespace Fixed;

However I couldn't get anything along this lines to work.
Anyone know how to do this?

Stuart

Jul 23 '05 #1
7 2266
"Stuart" <sj*@igs.net> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com
The stl::sort() that comes with Dev Studio 6 is broken (it hits the
degenerate case in a common situation). I have a replacement.
I would like to globally do "using namespace std; except use my
sort()".

I'd heard you can do this within a namespace:

namespace Fixed
{
using namespace std;
using Replacement::sort();
}
using namespace Fixed;

However I couldn't get anything along this lines to work.
Anyone know how to do this?

Stuart

From what I understand, using declarations (e.g., using Replacement::sort)
can only trump using directives (e.g., using namespace std;) by virtue of
the rule that identifiers declared in an inner scope hide identifiers
declared in an enclosing scope.

Using *directives* aren't declarations at all, they just put the identifiers
of a namespace in the global namespace. Using declarations, by contrast, are
declarations *in the current scope* and so can hide identifiers from an
enclosing scope, including the global namespace.

Consider your code:
namespace Fixed
{
using namespace std;
using Replacement::sort();
}
You should drop the () after sort. With this correction, the code means
that, within namespace Fixed, Replacement::sort hides the sort from the
global namespace (i.e., std::sort). Thus if you define a function within
namespace Fixed that calls sort, you won't have a name clash, e.g.,

namespace Fixed
{
using namespace std;
using Replacement::sort;
void foo(int *ptr, int size)
{
sort(ptr, ptr+size); // uses Replacement::sort
}
}

Your code:
using namespace Fixed;


just dumps everything from namespace Fixed into the global namespace. Thus
Replacement::sort joins std::sort in the global namespace and you have a
name clash in the global namespace. This isn't a problem if you are only
going to call foo subsequently, since there is only one foo. It is a problem
if you are going to call sort.

If you do need to call sort within a function (including the function
main() ) that is *not* defined within namespace Fixed, then you need to add
the using Replacement::sort; declaration to *each* such function or else
explicitly qualify sort when you use it, e.g.,

#include <algorithm>
#include <iostream>

namespace Replacement
{
template<class T>
void sort(T itbegin, T itend)
{
std::cout << "new sort function\n";
}
}

using namespace std;

int main()
{
using Replacement::sort;
int array[] = {4,6,3,8,1};
sort(array, array+5); // uses Replacement::sort
}

Note
1. The Replacement::sort declaration must be inside main() but it makes no
difference where using namespace std is.
2. I can't guarantee that your compiler is standard compliant in the way it
handles using directives/declarations.

--
John Carson

Jul 23 '05 #2
So does this mean my options are:

1. Touch every file that calls sort
2. Touch every file that calls something in std
3. Instead of doing
using namespace std;
in my global include file (yes I know some people think that's
just wrong, but it is convenient!) I should do:
using std::min;
using std::max;
.... (continue to enumerate everything we use)
using Replacement::sort;

Isn't there an easier way to override one specific name?
(I'm inclined to do option 3)

Stuart

Jul 23 '05 #3
"Stuart MacMartin" <sj*@igs.net> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com
So does this mean my options are:

1. Touch every file that calls sort
2. Touch every file that calls something in std
3. Instead of doing
using namespace std;
in my global include file (yes I know some people think that's
just wrong
Almost everyone, from what I have observed.
, but it is convenient!)
I should do:
using std::min;
using std::max;
.... (continue to enumerate everything we use)
using Replacement::sort;

Isn't there an easier way to override one specific name?
(I'm inclined to do option 3)


Well, since we have abandoned any pretence at scrupulous programming, you
could use a macro:

#include <algorithm>
#include <iostream>

namespace Replacement
{
template<class T>
void sort(T itbegin, T itend)
{
std::cout << "new sort function\n";
}
}

#define sort Replacement::sort

using namespace std;

int main()
{
int array[] = {4,6,3,8,1};
sort(array, array+5); // uses Replacement::sort
}

Personally, I would remove all using declarations/directives from the header
file and add them, where appropriate, in the .cpp files.

--
John Carson

Jul 23 '05 #4
"John Carson" <jc****************@netspace.net.au> wrote in message
news:da**********@otis.netspace.net.au

Well, since we have abandoned any pretence at scrupulous programming,
you could use a macro:


I mention this for completeness. It is a horrible idea. In particular,
macros don't respect scoping rules, so any attempt to use the identifier
sort (say, as a member function) will cause sort to be replaced by
Replacement::sort.

--
John Carson

Jul 23 '05 #5
Don't worry, I wasn't about to do that.

We introduced "using std;" to force using a standard min and max.
We wanted to be sure that any conflict in names was caught (and we
just hit another moving to a new redhat platform) rather than
inadvertently
using the wrong one - one that might not be what we expect. And yes
we found some that didn't do what std::min and max do (though I can't
recall the details) I can handle that case by doing "using std::min;
using std::max;" globally (and similarly any other routine where we
ALWAYS mean the std one).

Does it offend your sensibilities to decide globally that certain
routines are used? e.g. globally do using Replacement::sort;

Stuart

Jul 23 '05 #6
Stuart MacMartin wrote:
So does this mean my options are:

1. Touch every file that calls sort
2. Touch every file that calls something in std
3. Instead of doing
using namespace std;
in my global include file (yes I know some people think that's
just wrong, but it is convenient!) I should do:
using std::min;
using std::max;
.... (continue to enumerate everything we use)
using Replacement::sort;

Isn't there an easier way to override one specific name?
(I'm inclined to do option 3)


Edit your compiler's header files and comment out std::sort .
(Or is there a problem with std::min and std::max?)

Jul 23 '05 #7
"Stuart MacMartin" <sj*@igs.net> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com
Don't worry, I wasn't about to do that.

We introduced "using std;" to force using a standard min and max.
We wanted to be sure that any conflict in names was caught (and we
just hit another moving to a new redhat platform) rather than
inadvertently
using the wrong one - one that might not be what we expect. And yes
we found some that didn't do what std::min and max do (though I can't
recall the details) I can handle that case by doing "using std::min;
using std::max;" globally (and similarly any other routine where we
ALWAYS mean the std one).

Does it offend your sensibilities to decide globally that certain
routines are used? e.g. globally do using Replacement::sort;

Stuart


A lot of the rationale for namespaces comes from using code from multiple
suppliers in the one project. You might decide that the global use of a
particular function is appropriate, but what happens if you use a third
party library that depends on using a different function? Putting something
in a header file so as to deliberately create a name clash where the wrong
function is used in some legacy code is a useful tactic, but that doesn't
mean you have to leave it there after the uses of the wrong function have
been identified. One perhaps non-obvious problem with putting using
directives / declarations in header files is that it means that program
behaviour may depend on the order in which headers are included, which is a
fragility that should be avoided if possible.

If your using directives/declarations only occur in a single header file and
if you manage to always include it first, then you have a situation in which
you just have a whole lot of identifiers in the global namespace throughout
your program. This needn't be a huge problem, particularly if you make
little use of third party libraries. After all, it is how programs were
written before namespaces became part of the language. If you have a large
project and it would be a lot of work to change it, then you might decide to
live with this. You do, however, give up some of the benefits of namespaces.

There are circumstances in which a less-than-ideal design makes economic
sense for an existing project, given the cost of change (and, for small
projects, the problems that arise from less-than-ideal design, if any, are
often small enough to be managed manually). That is a judgement for you to
make.

--
John Carson

Jul 23 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by Aaron Broad | last post: by
10 posts views Thread by Paul Schneider | last post: by
6 posts views Thread by Der Andere | last post: by
5 posts views Thread by Lieven De Keyzer | last post: by
7 posts views Thread by yinglcs | last post: by
1 post views Thread by Varun Kacholia | last post: by
2 posts views Thread by thinktwice | last post: by
3 posts views Thread by mweltin | last post: by
5 posts views Thread by feverzsj | last post: by
reply views Thread by suresh191 | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.