Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typedef resolution across namespaces

I am currently confused with the way "using (namespace)" statements work in C++.

I have:

//somewhere in included headers
typedef unsigned int uint;

namespace mine {
    typedef unsigned int uint;
}
namespace other {
    using namespace mine;
    void foobar () {
        uint offender = i;
    }
}

Results in (paraphrased):
reference to 'uint' is ambiguous. candidates are
typedef unsigned int uint
and
typedef unsigned int mine::uint

Meanwhile, when I do

namespace other {
    using namespace mine;
    using mine::uint;

    void foobar () {
        uint offender = i;
    }
}

Everything works fine. It seems strange to me that "using identifier;" changes the visibility of other typedef definition (conceals the global one?). Can someone point me to what kind of rules in C++ govern resolution of typedefs across namespaces?

like image 428
Marcin K Avatar asked Feb 17 '11 22:02

Marcin K


People also ask

Should typedef be in namespace?

You may place it almost anywhere that you could otherwise place a preprocessing directive. A typedef can go either outside a namespace (which makes it global and causes it to apply everywhere), or inside (which causes it to be scoped to that namespace).

Is typedef scoped?

A typedef is scoped exactly as the object declaration would have been, so it can be file scoped or local to a block or (in C++) to a namespace or class.


2 Answers

Your original code confuses the compiler, because the uint can be either

::uint

or

::mine::uint

therefore compiler throws that error message to you. In the "fix", the using mine::uint explicitly specified that ::mine::uint shall be preferred.

However, typedef conflict shall be avoided IMO. It makes the code so hard to maintain.

like image 25
Peon the Great Avatar answered Oct 27 '22 22:10

Peon the Great


A name made visible by a using-directive appears in the nearest enclosing scope that contains [- directly or indirectly -] both the using-directive and the nominated namespace. (7.3.4 [namespace.udir])

This means that both uint declarations appear at the global namespace scope when looked up after the using-directive in other.

A using-declaration, like any other declaration, declares a name at the scope in which it appears. This is why, in the second example, using mine::uint; hides the uint introduced by using namespace mine; as the latter appears to come from the global scope.

like image 100
CB Bailey Avatar answered Oct 27 '22 22:10

CB Bailey