candidate standard functions for 'using' - c++

I knew the technique of using std::swap to enable via ADL the use of user defined swap functions, but I was not aware that this should be applied also to some other functions. For example I was writing abusively std::abs in template code wheras I should have used something like:
template <class Int> void f(Int i) {
using std::abs;
Int j = abs(i);
// ...
}
What standard function can you think of which should be used this way?
On a side note: g++ puts abs in the global namespace when including cstdlib (in fact ctsdlib includes stdlib.h (which defines the function abs) and does a #undef abs...), what does the standard says?

This is from the standard :
3.4.6 Using-directives and namespace aliases
[basic.lookup.udir]
When looking up a namespace-name in a using-directive or
namespace-alias-definition, only namespace
names are considered.
Therefore, you can use the keyword using to import variable, types and functions into the current namespace.
EDIT
You can import anything you like into the current namespace, but you should care for namespace polution, therefore try not to use using in headers, but only in the source files.
Ideally, you shouldn't be using this keyword. I use it sometimes when I have deeply nested namespaces.

Related

Is it possible to import a function to the namespace, but not export it?

Is it possible to import a function (or other symbol) to a namespace but not export it? For example, I want to import std::string into the current namespace, but I don't want current::string to be visible.
namespace current {
using std::string;
string func();
}
current::string should not be a thing.
The use case is simply to cut down on typing (and constantly forgetting to std::string among others) and make the code a little more legible without all the namespace syntax cluttering the code.
Is it possible to import a function (or other symbol) to a namespace but not export it?
No.
A using directive will introduce all the symbols that refer to the name you use in the declaration and they will be visible to the users of current as if they were actually declared in the namespace itself.
The relevant part of the standard is in [namespace.udir]/1:
A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive. During unqualified name lookup (6.4.1), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace. [ Note: In this context, “contains” means “contains directly or indirectly”. — end note ]
"All problems in computer science can be solved by another level of indirection" – David Wheeler
In this case, it is definitely so:
namespace current {
namespace impl {
using std::string;
string func();
}
using impl::func;
}
Admittedly, there are costs:
It forces you to list every single type or function that you want to export from current, given that in C++ there is no way to exclude individual symbols from e.g. a using namespace. (Just regard that as a feature as it makes the contents of your API deliberate instead of coincidental.)
This will not work if you need to remain ABI compatible (the mangled name of func will change on all implementations I know of)
BTW, the namespace name current suggests that you might also have versioning in mind. The two approaches can be combined nicely, e.g.:
namespace _v1 {
namespace impl {
int func();
}
// Exports
using impl::func;
}
namespace _v2 {
namespace impl {
using std::string;
string func();
}
// Exports
using impl::func;
}
namespace current = _v2;
No, and your code is bad practice. While your particular example of std::string may not cause conflicts, unnamed lookup can pull references to other string's defined outside the scope of the namespace, leading to possibly redeclaration errors or unnamed lookup using a different name than you intended. This can happen for example: a) you or someone else in your code uses a name that conflicts with a library (like distance), b) a library uses a name that conflicts (like Boost), c) or different translation units pull in different names from outside scopes, causing similar code to have entirely different behavior.
Either fully qualify your declarations always or at least use using ::std::string.

Does C++ also reserve the standard library function names?

Suppose you define a function inside the translation unit with the name of function exactly matching with any of the standard library function.
As the compiler first looks for the definition in the translation unit(s) and then in the library file, so will this cause to use the own version of the function definition or will it cause a diagnostic?
No, the names of functions within namespace std are not reserved - at least, not in the sense that using the same names outside of namespace std is forbidden.
However, placing names within namespace std (except in a few cases, such as specialising certain template functions) gives undefined behaviour.
If you are getting the compiler complaining about ambiguity when calling your functions, where one of the functions has the same name as yours but is in namespace std, then the cause is probably a using namespace std in your code. The effect of that, when the compiler encounters a name, is that both your functions and those in namespace std are valid matches. If the compiler has no reason to prefer one over the other (e.g. they accept the same types of argument) the code will not compile. In that case, the solution is to remove the using namespace std from your code - there is no way to undo the effects of using namespace std other than removing it.
I'm not sure if I understand the question correctly (correct me if I am wrong) but say you have a function like so:
void sort( // blah blah
Or declaring the std namespace using namespace std (which you should not be doing)
When you call sort(...) within your translation unit, the compiler overloads the definitions and in this case your function has precedence.
But if you are calling the standard library function by explicitly defining the std namespace (using the scope resolution operator) like so
std::sort( // blah blah
it will use the std library function instead.
That's the reason why people say using namespace std; in C++ is a bad practice.
Because the function definition gets conflicted when you use the same function name which is already defined inside the namespace std leading to many unrelated errors.
Read this thread for more details:-
Why using namespace std; in C++ is considered a bad practice?

How to enforce use of "std::" namespace in GCC? [duplicate]

I am using only header files specific to C++ (e.g. <cstdlib>), however I still get globally-declared functions, and not just functions in the std namespace. Is there a way, perhaps a compiler switch, to prevent that?
For example, the following code:
#include <cstdlib>
float random() { return 0.0f; }
int main() { return 0; }
Fails to compile under linux, with the following error:
> g++ -c main.cpp main.o
main.cpp: In function ‘float random()’:
main.cpp:2:14: error: new declaration ‘float random()’
/usr/include/stdlib.h:327:17: error: ambiguates old declaration ‘long int random()’
or
> clang++ main.cpp -o main.o
main.cpp:2:7: error: functions that differ only in their return type cannot be overloaded
float random() { return 0.0f; }
/usr/include/stdlib.h:327:17: note: previous declaration is here
extern long int random (void) __THROW;
which is caused that stdlib.h "pollutes" the global namespace with its own random function.
Note, that I am not facing these problems when compiling on Windows, using Visual Studio.
<cstdlib> will always populate std namespace, and sometimes define global symbols, while <stdlib.h> will always define global symbols, and sometimes populate std namespace. This varies from implementation to implementation.
The standard writes:
Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).
Which means, that the compiler is allowed to put those symbols into global scope and std namespace at the same time.
Therefore, we see no advantages to prefer one header file over the other. Because they are both very likely to pollute the global scope.
However, it is still necessary to use std namespace when #include <cstdlib>, and do not use std when #include <stdlib.h>, to make sure your code can compile for all compiler implementations.
Advice: Do not use names in standard libraries. First, they are not guaranteed to work. (Note: Few compiler implementations actually keep the global scope clean when you #include <csomething>, so never depend on this.) Second, it will confuse code readers and maintainers, because almost everyone will assume standard names are actually standard, no matter where they come from.
You can declare your functions in their own namespaces to prevent declaration collision.
namespace MyFunc
{
float random() { return 0.0f; }
};
In general you should try to avoid redeclaring in the first place.
You can do this by either using namespaces or by splitting up your source into files which can include cstdlib and others which can use a static version of your (name clashing) function.
If this is not an options then go on reading. But be aware that the following might be very platform specific.
By just having a look at my cstdlib and stdlib.h here at my place I noticed that there is a switch by which cstdlib decides if it includes stdlib.h or just declares abort, atext and exit in the std namespace.
Obviously you pull in the stdlib.h branch. Looking further into this file I noticed the macro __BEGIN_NAMESPACE_STD and later on __END_NAMESPACE_STD. Maybe you could use this, but it is (as the name suggests) some implementation internal macro and should not be set directly by you. However, it should be there for some reason so you might have luck with searching for it.
After some more search it turned out that random is one of several functions (and declarations) which are not wrapped into __BEGIN_NAMESPACE_STD. Therefore, this is not a solution to the problem. (I found another macro _GLIBCPP_USE_NAMESPACES which seems to be used internally as well to #define __BEGIN_NAMESPACE_STD namespace std {).
So to sum it up: This is no viable path and you should use one of the described workarounds.
The standard explicitly permits <c???> headers to bring names of C standard functions to the global namespace.
usually I would prefer to keep your function names different from what is defined as a standard .
For ex here one could use function name as myRandom instead of random so that I can inform the people , who would be maintaining my code later on , that the function being used is NOT the one defined as a standard.

Using Directives in Implementation Files

In C++ Primer, there is one tips says:
One place where using directives are useful is in the implementation
files for the namespace itself.
I guess this is just for using shorthand names? I am not sure how it is different from just surrounding the implementation with
namespace namespace_name
{
}
Thanks.
That applies to modifications to your own namespaces. The purpose of using directives is to import symbols from a different namespace. For example, an infamous idiom:
namespace my_stuff
{
template <typename Container>
void my_fn( Container& xs )
{
using std::begin;
using std::end;
std::sort( begin(xs), end(xs) );
}
}
Everything happens in your my_namespace, but it makes available the std::begin() and std::end() functions if needed. If a more local definition for begin() and end() exists that better matches the Container type, then it will be used instead. If you had simply wrapped everything in the std namespace, this useful ability would be lost.
Hope this helps.
I am not sure how it is different from just surrounding the implementation with namespace namespace_name { }
This is to put your own code within a namespace, as opposed to using some name from another namespace. Say you write a draw function inside the Graphics namespace -- to do this, you wrap draw's code in namespace Math { void draw() { /* some code */ } } and to use it you'd do Graphics::draw. However, when you need to use a function, say, gamma in the Math namespace (which you didn't write), you've to call it Math::gamma for the compiler to know where to search for gamma. Alternatively, you may use shorthand, to drop the Math:: part.
I guess this is just for using shorthand names?
Yes, that's to allow identifiers from some namespace to be used without the qualifier. There are two ways to do it.
Using directive: Use all names in a namespace without qualification (e.g. using namespace Math;)
Using declaration: Use only some specified names without qualification (e.g. using Math::gamma) -- this is usually better than the former.
However, both are encouraged to be used only in an implementation/source file and not in a header to avoid some sources which may have its own copy of gamma and don't want to use Math::gamma, but since you've it in the header, it'll lead a clash of the names. More details on "using namespace" in c++ headers.

What's the purpose of: "using namespace"?

There are convincing arguments against using namespace std, so why was it introduced into the language at all? Doesn't using namespace defeat the purpose of namespaces? Why would I ever want to write using namespace? Is there any problem I am not aware of that is solved elegantly by using namespace, maybe in the lines of the using std::swap idiom or something like that?
For one thing, this is the way to use operator overloads in a namespace (e.g using namespace std::rel_ops; or using namespace boost::assign;)
Brevity is also a strong argument. Would you really enjoy typing and reading std::placeholders::_1 instead of _1? Also, when you write code in functional style, you'll be using a myriad of objects in std and boost namespace.
Another important usage (although normally one doesn't import whole namespaces) is to enable argument-dependent look-up:
template <class T>
void smart_swap(T& a, T& b)
{
using std::swap;
swap(a, b);
}
If swap is overloaded for some type of T in the same namespace as T, this will use that overload. If you explicitly called std::swap instead, that overload would not be considered. For other types this falls back to std::swap.
BTW, a using declaration/directive does not defeat the purpose of namespaces, since you can always fully qualify the name in case of ambiguity.
Most of the times it is just a shortcut for writing code. You can import names into your enclosing context. I usually restrict it to .cpp files, because when you include an using directive into a .h file, it pollutes all the files in which it is included. Another good practice is restricting the using namespace to the most enclosing environment possible, for instance, inside of a method body declaration. I see it as a convenience, no more, and similar to namespace aliasing, such as:
namespace po = boost::program_options;
and then you can write
po::variables_map ...
The main reason why using namespace was introduced was backwards compatibility: If you have lots of pre-namespace code using lots of (pre-standard versions of) standard library functions and classes, you want a simple way to make that code work with a standard conforming compiler.
BTW, the argument dependent lookup rules at least for C++98 mean that using namespace std::rel_ops will not do what you want in templates (I don't know if this changed in a later version of the standard).
Example:
template<typename T> bool bar(T t)
{
return t > T();
}
namespace foo
{
class X {};
bool operator<(X, X);
}
using namespace std::rel_ops;
int main()
{
X x;
bar(x); // won't work: X does not have operator>
}
Note that putting the using namespace in namespace foo won't help either.
However, using declarations in the right spot help:
template<typename T> bool bar(T t)
{
return t > T();
}
namespace foo
{
class X {};
bool operator<(X, X);
using std::rel_ops::operator>;
}
int main()
{
X x;
bar(x); // now works: operator> found per ADL via the using declaration in `namespace foo`
}
People specifically object to using namespace std; but not to using namespace BigCorp; or to referring to std::cout (which is using the namespace, just not using it, if you know what I mean.) Also, most of the objections to using namespace std are in a header file. In a source file, where the effects can be immediately seen, it's less harmful.
Namespaces are an incredibly useful concept that allow me to have a class called Date even though a library I'm using has a class called Date. Before they were added to the language, we had to have things like GCDate and GCString (my company, Gregory Consulting, predates std::string). Making use of namespaces (with or without the using keyword) lets us all write cleaner, neater code. But when you have to say Gregcons::string every time, you kind of lose the cleaner, neater part. [Disclaimer: I don't actually use my own string class anymore - imagine some appropriate name conflict.] That's the appeal of the using statement. Keep it out of headers, don't apply it to std, and you should generally stay out of trouble.
I find it useful when working with libraries with deeply nested namespaces. The Boost library is one such example. Imaging typing boost::numeric::ublas::matrix<double> m all over the place ...
The thing to avoid is doing using namespace in a header file as this has the potential for royally screwing up any program that includes said header. Always place using namespace statements in .cpp/.cxx files, so that it's restricted to file scope.
"Namespaces allow to group entities like classes, objects and functions under a name. This way the global scope can be divided in "sub-scopes", each one with its own name. Where identifier is any valid identifier and entities is the set of classes, objects and functions that are included within the namespace"
More information here:
http://www.cplusplus.com/doc/tutorial/namespaces/