When to use a namespace or a struct? - c++

I was just reading a little bit on them from http://www.cplusplus.com/doc/tutorial/namespaces/
and it seems like a struct is capable of the same things? Or even a class for that matter. Maybe someone here can better define what a namespace is, and how it differs from a struct/class?

Namespaces and class-types are not capable of the same things. Namespaces are mainly used to group types and functions together to avoid name collisions, while class-types hold data and operations that work on that data.
To just group functions and objects by using a class-types you'd have to make them static:
struct X {
static void f();
};
Without static you'd have to create instances of the class-types to use them. A namespace is much better suited here:
namespace X {
void f();
}
Another important thing are using declarations and directives:
namespace X {
void f();
void g();
}
void h() {
using X::f;
f(); // f() now visible in current scope
using namespace X;
f(); g(); // both visible
}
With class-types there simply is no mechanism that allows that.
What class-types give you over namespaces is that you can have multiple instances with differing state - if you need that use a class-type.

Well, seems everyone's going at it, so I'll add my own arguments.
First things first, namespace and struct are completely different beasts: they have different syntax and different semantics.
The obvious:
a struct introduces a type, you can use as templates argument
a namespace can be spread in several files
Syntactically:
both can be "aliased", namespace with namespace ns = mylong::name::space; and struct with typedef mylong::name::Space lilstruct;
ADL (or Argument Dependent Lookup) is tailored for namespaces
Semantically:
a namespace only defines a scope for the definition of symbols, which allows to group together objects that work together (classes and free-functions) while isolating them for the rest of the world (name clashes). As such it often represents a logical unit of work within the project (for small projects, there is a single namespace).
a struct or class defines a logical binding between data and the methods to act upon it, which is the corner stone of encapsulation. It usually has one clear responsability and a number of invariants.
Note that sometimes a struct or class is just used to bind together objects that work together without having any logic, for example struct Person { std::string name, firstName; };.
That being said: there is no point in C++ for a struct of static methods. It's just a perversion from Java or C# and their "pure" OO approach. C++ supports free functions, so there is no point not using them, especially since it's better for encapsulation (they don't have access to private/protected parts, so you can't mess up an invariant and they don't depend on the representation of the class either).

If it can be done with a namespace, use a namespace.
A struct does much more than defining a scope. It defines a type.

If you don't want people to use the "using" feature of C++ with your class, which can be dangerous and is often ill advised in complex code, then go ahead and use struct with statics.
In other words: if your functions should always be referred to with "group::function", then you can box in your users by declaring as a struct.
In addition, and importantly, you can forward-declare structs in older versions of C++. You cannot do this with namespaces until C++ 11.
Consider:
std::string out zip::pack(const std::string &in)
std::string out zip::unpack(const std::string &in)
In this case, requiring users to specify zip:: makes sense. It's a short, specific and informative. And the names of the underlying functions are ambiguous without it. Use a struct with statics.
Consider:
std::string out CorpDataUtils::zipPack(const std::string &in)
std::string out CorpDataUtils::zipUnpack(const std::string &in)
These should certainly be in a namespace. The namespace name is long, and uninformative, probably more to do with the organization of whoever is maintaining it - which is fine... but really it should be a namespace... not a struct.

In C++ a struct is exactly the same as a class, except structs are public by default. Classes are private. So whenever you want to group free functions together use a namespace. When you want to group data and functions, use a struct/class, and optionally a namespace around it all.
Notice that If you put your functions in a struct then you would have to have an instance of your struct when you want to call those functions, unless they are static.

When creating your own library, it's normally good practice to namespace all your exported functions and classes.
That way, if someone includes your library, they won't be polluting their namespace, and there is less likelyhood of name clashes.

This is a counter example where using a struct instead of a namespace gives some unexpected benefits.
I wanted to generalise a solution to a 2D problem to K dimensions. The 2D solution was enclosed in a namespace.
Templates to the rescue. I started changing the implementation:
struct Point;
to
template< size_t DIMS >
struct Point;
I needed to template most classes, structs, and functions. That was tedious, repetitive, and error prone. And then I had this mischevios idea. I changed
namespace KDimSpace {
to
template< size_t DIMS >
struct KDimSpace {
and that was pretty much it. I could rip off all template< size_t DIMS > junk inside. This is so much easier - the number of dimensions DIMS is declared only once and used consistently by all types and functions.
And then, there is one more thing - rather than hiding internals of the implementation behind ::detail (sub)namespace there is public: and private:!
There are two annoyances:
functions have to be marked as static
it is not possible to define operators (e.g. operator<< for std::ostream) because operators cannot be marked as static (and then ADL might get in the way as well).
Bottom line - C++ could be a better language with fewer primitives not more. I would like namespaces to be as close to structs as classes are.

Related

Scoping functions within namespace versus within class [duplicate]

This question already has answers here:
Namespace + functions versus static methods on a class
(9 answers)
Closed 3 years ago.
I've got a bunch of functions(func1(),func2(),...) in a header file to which I want to give some scope. I know of 2 implementations:
class bunchOfFunctions
{
public:
static void func1();
static void func2();
...
};
namespace bunchOfFunctions
{
void func1();
void func2();
...
};
In both the options, I can access the functions in the same way i.e. by bunchOfFunctions::func(). I prefer the namespace method(lesser typing), but I've seen the 1st method of implementation also at my workplace.
Which option is better? Is there any other option?
Apart from StroryTeller highlighted points,
Spread: A namespace can be spread into multiple files where as Class must be defined in a single place.
Readability and Understandability: Generally developers inherent understanding of what a Class is and what a namespace is.
"Better" depends on your definition for better. What qualities are you looking for in the scoping? There is no one size fits all answer here. But here are some properties of both approaches:
Necessity to qualify the function name.
With a class you must write bunchOfFunctions::func1() when
utilizing those functions. Meanwhile a namespace allows you to pull
a function in with a using declaration
using bunchOfFunctions::func1;
and use it unqualified in most scopes. If you wished you could even make all the members of the namespace available to unqualified name lookup with a using directive. Classes don't have an equivalent mechanic.
Aliasing.
There is no difference. To alias the class one writes
using BOF = bunchOfFunctions;
while aliasing the namespace is done with
namespace BOF = bunchOfFunctions;
Privacy.
A class can have private members. So you could put function declarations in there under a private access specifier and use them in public inline members. Namespaces have no such mechanism. Instead we rely on convention and put declarations under a "do not touch this" internal namespace, often called bunchOfFunctions::detail.
Argument dependent lookup.
C++ has a mechanism that allows it to find function declarations from an unqualified call, by examining the namespaces that contain the arguments to the call. For that to work, the function must be in an actual namespace. Static members of classes are not subject to such a lookup. So for any member types you may have, only a namespace will allow calls via ADL.
These four are off the top of my head. Judge your needs for yourself. As for "Is there any other option?", those are the only two ways you have to group such functions in C++ today. In C++20, we'll have modules! That will offer another level of grouping for code.
In addition the information given above I would add that going back to the standard definition of what a class and what a namespace is can help with decisions like this.
A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.
In object-oriented programming, a class is an extensible program-code-template for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods).
While these may sound similar they are rather specific. So if your functions are related, but not necessarily to the same object I would think hard about whether to put them in a class; particularly if grouping these functions together in a class may violate the Single Responsibility Principle: https://en.wikipedia.org/wiki/Single_responsibility_principle

making a typedef local to a file or subclasses

I'm consolidating 2 programs into one, and in 2 different files (I have many files), I have a typedef with the same name, different types though.
These types will be used in completely different parts of the program and will never talk to each other, or be used interachangely.
I can of cause just do a search replace in one of the files, but I was wondering if there is another solution to this.
Something like binding a typedef to a specific file.
Or making a typedef local to a class and it's subclasses.
Thanks
typedefs are always "local to a file". So it is not exactly clear what you mean by "making it local to a file". Typedef does not introduce an entity with its own linkage, it simply creates an alias to an existing type. For that reason the problem of "making it local to a file" simply does not exist. Each typedef is only visible in the translation unit (file) in which it is declared. So, if you can make sure that your identically named typedefs never meet each other in a common translation unit, you problem is formally solved.
It is not a good programming practice though to have the same typedef-name refer to different types in different files, unless these files are naturally separated somehow (like belong to different libraries, or something like that).
Otherwise, you can always rename one of the typedefs, or make it a class member or a namespace member. Keep in mind though that in general case the making a typedef member of a class will require virtually the same kind of effort as renaming it: the references to that typedef will have to be updated in every place in which they are present. Namespaces might be a bit easier, since with namespaces you can use using directive.
But again, if your typedefs are only referrd from two disjoint sets of files, then the problem does not formally exist. If there are files that are supposed to use both typedefs, then the effort you'll have to spend fixing these files will be equivalent to renaming the typedefs (regardless of the method you finally choose).
You can encapsulate those typedef inside a namespace:
namespace N1 {
typedef int T;
}
namespace N2 {
typedef int T;
}
And in whatever file you want to use first typedef simply declare:
using namespace N1;
same thing for the other one also.
[...]Or making a typedef local to a class
and it's subclasses.
Well, that's simple:
struct A
{
typedef int X;
};
struct B : A
{
X a;
};
struct C
{
typedef double X;
};
Typedefs are scoped in C++.

Why field inside a local class cannot be static?

void foo (int x)
{
struct A { static const int d = 0; }; // error
}
Other than the reference from standard, is there any motivation behind this to disallow static field inside an inner class ?
error: field `foo(int)::A::d' in local class cannot be static
Edit: However, static member functions are allowed. I have one use case for such scenario. Suppose I want foo() to be called only for PODs then I can implement it like,
template<typename T>
void foo (T x)
{
struct A { static const T d = 0; }; // many compilers allow double, float etc.
}
foo() should pass for PODs only (if static is allowed) and not for other data types. This is just one use case which comes to my mind.
Because, static members of a class need to be defined in global a scope, e.g.
foo.h
class A {
static int dude;
};
foo.cpp
int A::dude = 314;
Since the scope inside void foo(int x) is local to that function, there is no scope to define its static member[s].
Magnus Skog has given the real answer: a static data member is just a declaration; the object must be defined elsewhere, at namespace scope, and the class definition isn't visible at namespace scope.
Note that this restriction only applies to static data members. Which means that there is a simple work-around:
class Local
{
static int& static_i()
{
static int value;
return value;
}
};
This provides you with exactly the same functionality, at the cost of
using the function syntax to access it.
Because nobody saw any need for it ?
[edit]: static variables need be defined only once, generally outside of the class (except for built-ins). Allowing them within a local class would require designing a way to define them also. [/edit]
Any feature added to a language has a cost:
it must be implemented by the compiler
it must be maintained in the compiler (and may introduce bugs, even in other features)
it lives in the compiler (and thus may cause some slow down even when unused)
Sometimes, not implementing a feature is the right decision.
Local functions, and classes, add difficulty already to the language, for little gain: they can be avoided with static functions and unnamed namespaces.
Frankly, if I had to make the decision, I'd remove them entirely: they just clutter the grammar.
A single example: The Most Vexing Parse.
I think this is the same naming problem that has prevented us from using local types in template instantiations.
The name foo()::A::d is not a good name for the linker to resolve, so how should it find the definition of the static member? What if there is another struct A in function baz()?
Interesting question, but I have difficulty understanding why you'd want a static member in a local class. Statics are typically used to maintain state across program flow, but in this case wouldn't it be better to use a static variable whose scope was foo()?
If I had to guess why the restriction exists, I'd say it was something to do with the difficulty for the compiler in knowing when to perform the static initialisation. The C++ standards docs might provide a more formal justification.
Just because.
One annoying thing about C++ is that there's a strong dependence on a "global context" concept where everything must be uniquely named. Even the nested namespaces machinery is just string trickery.
I suppose (just a wild guess) that one serious technical issue is working with linkers that were designed for C and that just got some tweak to get them working with C++ (and C++ code needs C interoperability).
It would be nice to be able to get any C++ code and "wrap it" to be able to use it without conflicts in a larger project, but this is not the case because of linkage problems. I don't think there is any reasonable philosophical reason for forbidding statics or non-inline methods (or even nested functions) at the function level but this is what we got (for now).
Even the declaration/definition duality with all its annoying verbosity and implications is just about implementation problems (and to give the ability to sell usable object code without providing the source, something that is now a lot less popular for good reasons).

How important is consistent usage of using declarations?

Most of the research I've done on the use of using declarations, including reading relevant sections of various style guides, indicates that whether or not to use using declarations in C++ source files, as long as they appear after all #includes, is a decision left to the coder. Even the style guides I read, which usually come down on one side or the other of such common disputes for the sake of consistency, are fairly flexible in this regard.
My question is, given this high degree of flexibility, how important is it to use a consistent style? For example, suppose an author wrote something like
using std::vector;
vector<T> v;
std::cout << v[0] << std::endl;
Is the inconsistent application of using on std::vector but not std::cout or std::endl generally considered acceptable, or would it be considered undisciplined?
I think the whole point of using is that you use it inconsistently among names. Names you need very frequently in some block can be declared locally with a using declaration, while others are not. I don't see a problem with that.
Declaring a name to have namespace scope is always much harder to take. I think if the name clearly is known to belong to a particular namespace so that confusing it with other namespaces won't occur, It won't hurt to put a using declaration if it makes your code more readable.
I am now a strong proponent for explicitly stating the namespace (ie no 'using')
Most peoples namespace history goes like this (in non trivial, >100kloc projects)
Innocence -> style 1
using namespace std;
Ouch -> style 2
using std::string;
using std::vector;
OK, enough already -> style 3
std::string foo = "xxx";
Assuming you don't say using namespace std; anywhere, I don't think most developers care one way or another in other people's code. The only thing that might bother them is the overuse of the std:: qualifier --- that is if you're saying "std::vector" 20 times in the function, maybe it's time for a "using std::vector". Otherwise, no one should care.
Sometimes, in my own code, I'll use the "std::" qualifier specifically to indicate that this is the only place that I'm using that identifer.
I try for not using using (no pun intended).
For saving typing, I like to do typedefs, e.g.:
typedef std::vector< int > IntVector;
typedef std::vector< Foo > FooVector;
This is less an answer than a counterpoint to a few other answers that have advocated always explicitly including the namespace as part of the name. At times, this is a poor idea. In some cases, you want to use a name that's been specialized for the type at hand if it exists, but use a standard-provided alternative otherwise.
As a typical example, let's consider a sort function. If you're sorting some objects of type T, you're going to end up swapping items. You want to use a special swap(T &, T&) if it exists, but template <class T> std::swap otherwise.
If you try to specify the full name of the swap you're going to use explicitly, you have to specify one or the other -- either you specify a specialized version, and instantiating your sort over a type that doesn't define it's own swap will fail, or else you specify std::swap, and ignore any swap that's been provided specifically for the type you're sorting.
using provides a way out of this dilemma though:
using namespace std;
template <class T>
mysort(/* ... */ ) {
// ...
if (less(x[a], x[b])
swap(x[a], x[b]);
// ...
}
Now, if the namespace in which T is found contains a swap(T &, T&), it'll be found via argument dependent lookup, and used above. If it doesn't exist, then std::swap will be found (and used) because the using namespace std; made it visible as well.
As an aside, I think with one minor modification, using namespace x; could be made almost entirely innocuous. As it stands right now, it introduces the names from that namespace into the current scope. If one of those happens to be the same as a name that exists in the current scope, we get a conflict. The problem, of course, is that we may not know everything that namespace contains, so there's almost always at least some potential for a conflict.
The modification would be to treat using namespace x; as if it created a scope surrounding the current scope, and introduced the names from that namespace into that surrounding scope. If one of those happened to be the same as a name introduced in the current scope, there would be no conflict though -- just like any other block scoping, the name in the current scope would hide the same name from the surrounding scope.
I haven't thought this through in a lot of detail, so there would undoubtedly be some corner cases that would require more care to solve, but I think the general idea would probably make a lot of things quite a bit simpler anyway.

Should every class have its own namespace?

Something that has been troubling me for a while:
The current wisdom is that types should be kept in a namespace that only
contains functions which are part of the type's non-member interface (see C++ Coding Standards Sutter and Alexandrescu or here) to prevent ADL pulling in unrelated definitions.
Does this imply that all classes must have a namespace of their own? If
we assume that a class may be augmented in the future by the addition of
non-member functions, then it can never be safe to put two types in the
same namespace as either one of them may introduce non-member functions
that could interfere with the other.
The reason I ask is that namespaces are becoming cumbersome for me. I'm
writing a header-only library and I find myself using classes names such as
project::component::class_name::class_name. Their implementations call
helper functions but as these can't be in the same namespace they also have
to be fully qualified!
Edit:
Several answers have suggested that C++ namespaces are simply a mechanism for avoiding name clashes. This is not so. In C++ functions that take a parameter are resolved using Argument Dependent Lookup. This means that when the compiler tries to find a function definition that matches the function name it will look at every function in the same namespace(s) as the type(s) of its parameter(s) when finding candidates.
This can have unintended, unpleasant consequences as detailed in A Modest Proposal: Fixing ADL. Sutter and Alexandrescu's rule states never put a function in the same namespace as a class unless it is meant to be part of the interface of that class. I don't see how I can obey that rule unless I'm prepared to give every class its own namespace.
More suggestions very welcome!
No. I have never heard that convention. Usually each library has its own namespace, and if that library has multiple different modules (e.g. different logical units that differ in functionality), then those might have their own namespace, although one namespace per library is sufficient. Within the library or module namespace, you might use namespace detail or an anonymous namespace to store implementation details. Using one namespace per class is, IMHO, complete overkill. I would definitely shy away from that. At the same time, I would strongly to urge you to have at least one namespace for your library and put everything within that one namespace or a sub-namespace thereof to avoid name clashes with other libraries.
To make this more concrete, allow me to use the venerable Boost C++ Libraries as an example. All of the elements within boost reside in boost::. There are some modules within Boost, such as the interprocess library that have its own namespace such as boost::interprocess::, but for the most part, elements of boost (especially those used very frequently and across modules) simply reside in boost::. If you look within boost, it frequently uses boost::detail or boost::name_of_module::detail for storing implementation details for the given namespace. I suggest you model your namespaces in that way.
No, no and a thousand times no! Namespaces in C++ are not architectural or design elements. They are simply a mechanism for preventing name clashes. If in practice you don't have name clashes, you don't need namespaces.
To avoid ADL, you need only two namespaces: one with all your classes, and the other with all your loose functions. ADL is definitely not a good reason for every class to have its own namespace.
Now, if you want some functions to be found via ADL, you might want to make a namespace for that purpose. But it's still quite unlikely that you'd actually need a separate namespace per class to avoid ADL collisions.
Probably not. See Eric Lippert's post on the subject.
Couple things here:
Eric Lippert is a C# designer, but what he's saying about bad hierarchical design applies here.
A lot of what is being described in that article has to do with naming your class the same thing as a namespace in C#, but many of the same pitfalls apply to C++.
You can save on some of the typedef pain by using typedefs but that's of course only a band-aid.
It's quite an interesting paper, but then given the authors there was a good chance it would be. However, I note that the problem concerns mostly:
typedef, because they only introduce an alias and not a new type
templates
If I do:
namespace foo
{
class Bar;
void copy(const Bar&, Bar&, std::string);
}
And invoke it:
#include <algorithms>
#include "foo/bar.h"
int main(int argc, char* argv[])
{
Bar source; Bar dest;
std::string parameter;
copy(source, dest, parameter);
}
Then it should pick foo::copy. In fact it will consider both foo::copy and std::copy but foo::copy not being template will be given priority.