40

I am writing a library with mutiple dependent modules. When I include a file from a different module, should I resolve the namespace with:

using namespace project1::namespace1;
class1 obj;

or

typedef project1::namespace1::class1 class1;
class1 obj;

What are the pros/cons of each approach? I read somewhere that we should use typedef in .H files and using in .C files, is this advisable?

One problem I have encountered with 'typedef' is it leads to namespace ambiguity if I include both original class and the class with 'typedef' in a third module.

vidit
  • 957
  • 1
  • 8
  • 23
  • 18
    An alternative is `using project1::namespace1::class1;` – hmjd Apr 26 '12 at 10:25
  • 1
    "It depends". THere's no one right answer here. – bmargulies Apr 26 '12 at 10:26
  • @bmargulies Thanks. Could you please elaborate? – vidit Apr 26 '12 at 10:28
  • C++ does not have a coherent design structure, as it added it's own features, gradually over time, on top of C. So it's got both 'using' and 'typedef', and for the case of one single item, they are pretty hard to distinguish in utility. – bmargulies Apr 26 '12 at 10:30
  • "we should use 'typedef' in .H files and 'using' in .C files" - I disagree with using a whole namespace in an .h file since that means you're polluting the global namespace with things the .c file might not expect. The .c file is its own compilation unit and can do whatever it wants. However I think hmjd's solution is better than a typedef. – Rup Apr 26 '12 at 10:30

4 Answers4

76

The two options you state are not equivalent. This one:

using namespace project1::namespace1;

pulls in everything from the namespace, giving you little control and making clashes likely. I see only cons, and no pros here.

But you don't need to use a typedef to bring in a single symbol, you can use

using project1::namespace1::class1;

Whether you use this or the typedef doesn't make too much of a difference. But bear in mind that typedef is limited to types and enumerations, whereas using can refer to values, functions, etc:

namespace X {
  const int x{42};
  enum Fruit{Apple, Pear};
}

using X::x; // OK
typedef X::x xx; // Error! 'x' in namespace 'X' does not name a type

so the two expressions are not completely equivalent.

Boris Dalstein
  • 7,015
  • 4
  • 30
  • 59
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
8

You should never use using or typedef in a header file just for the sake of making names easier to type.

In the source file, it's up to you. It seems to be considered good practice to write out the whole name, as it makes it very clear what you meant. If your namespace is too long, you can use a namespace alias to reduce clutter, but still keep the meaning clear: namespace ns = project1::namespace1;

Either way, if you're going to import symbols into the global namespace, use using, not typedef. typedef is used mainly when you want to call the type by a different name, many times because it is a template - for example, my_map instead of std::map<std::string, my_type>, which is still clear, but much nicer to type.

Also, see this question: Why is "using namespace std" considered bad practice?

Community
  • 1
  • 1
parkovski
  • 1,503
  • 10
  • 13
  • 6
    never use `typedef` in a header? Seriously? -1 . It is a standard practice to typedef several types to be used in the rest of app, and put them all in a single header. Examples include Uint8 in libsdl, and quint16 in Qt 4. – SigTerm Apr 26 '12 at 10:46
  • 3
    @SigTerm: parkovski frowns on abbreviating incoming types for local usage within the header. Using typedefs to define your exposed API is totally different and ok. – David Schmitt Apr 26 '12 at 12:02
  • 6
    @DavidSchmitt: Both "usage patterns" you mentioned are identical and represent the same thing - you make central header and use types declared in that header. Whether it is for "import"/"export" is irrelevant. parkovski's suggestions sounds unreasonable, because there are many places in *.h where you can place typedef - you can enclose it within class, namespace, etc., which is safe. Also, typedef does not cause a mess. So no matter how you look at it, "no typedef in *.h" sounds like an pointless artificial restriction on a coding style - there are no benefits, so this rule shouldn't be used. – SigTerm Apr 26 '12 at 15:19
  • @SigTerm I don't think you read the rest of that sentence. Standard C has tons of typedefs in headers that are very useful (`size_t`, `ptrdiff_t` for example). The difference is those are a part of the API that serves a specific purpose, not just a shortcut for someone "cuz i dont liek 2 type". – parkovski Apr 28 '12 at 00:08
6

The most clear way is not use any of those methods - just write new project1::namespace1::class1().

Benj
  • 31,668
  • 17
  • 78
  • 127
IProblemFactory
  • 9,551
  • 8
  • 50
  • 66
3

use using project1::namespace1::class1

Or, you can limit your using namespce in a local scope, both for your convenience and not polute the global namespace.

void function()
{
    using namespace project1::namespace1;

    class1 obj;

    ...
}
vidit
  • 957
  • 1
  • 8
  • 23
Lyn
  • 699
  • 1
  • 7
  • 17