How do I put some code into multiple namespaces wi

2020-07-02 05:37发布

Assume I have the method defined in the two different namespaces:

namespace foo
{
    void print()
    {
        //do work...
    }
}

namespace bar
{
    void print()
    {
        //do work...
    }
}

The foo::print() and the bar::print() functions are absolutely equal. My project uses the numerous calls of these functions.

Is there a way to remove one of the print() definitions without changing the calls of these function? I mean something like the following (of course, C++ language doesn't allow this construction, it's just an example):

namespace foo, bar  //wrong code!
{
    void print()
    {
        //do work...
    }
}

If there is no way to refactor the code as I want, please tell me, do you like the following decision? Will you be glad if your project contains such code? :)

namespace foo
{
    void print()
    {
        //do work...
    }
}

namespace bar
{
    void print()
    {
        foo::print();
    }
}

ADD:

Thank you guys, I'm fully satisfied by your answers. Just one moment I want you to clarify: is there a difference between using ::foo::print and using foo::print?

5条回答
▲ chillily
2楼-- · 2020-07-02 05:46

Probably the best solution is this:

namespace foo
{
    void print()
    {
        //do work...
    }
}

namespace bar
{
    void print()
    {
        foo::print();
    }
}

However you can write:

namespace foo
{
    void print()
    {
        //do work...
    }
}

namespace bar
{
    void print()
    {
        //do work...
    }
}

This is not recomended, but there is no evil. Compilers are smart enough to understand that these two functions are the same and can be used the same assembly code.

Remember, namespace keyword is for programmers, compiler doesn't care about them very much, for compiler namespaces are like prefix for functions/methods/classes.

查看更多
贪生不怕死
3楼-- · 2020-07-02 05:48

With a using declaration:

namespace bar
{
    using ::foo::print;
}
查看更多
Emotional °昔
4楼-- · 2020-07-02 05:59

Sample

namespace Q {
    namespace V {
        void f(); // enclosing namespaces are the global namespace, Q, and Q::V
        class C { void m(); };
        }
        void V::f() { // enclosing namespaces are the global namespace, Q, and Q::V
        extern void h(); // ... so this declares Q::V::h
        }
        void V::C::m() { // enclosing namespaces are the global namespace, Q, and Q::V
    }
}
查看更多
叛逆
5楼-- · 2020-07-02 06:07

You can achieve this with a using declaration.

namespace foo
{
    void print()
    {
        //do work...
    }
}

namespace bar
{
    using foo::print;
}

EDIT

Regarding the difference between ::foo::print and foo::print: prepending a qualified name with :: means that you explicitly refer to the one in the global namespace. This can be used to select the global one, even if there is another item with the same name closer in scope.

查看更多
Root(大扎)
6楼-- · 2020-07-02 06:07

How about using declaration:

namespace foo
{
    void print()
    {
        // do work ...
    }
}

namespace bar
{
    using ::foo::print;
}

Using ::foo::print instead of foo::print is an important point. If you would have another foo inside of bar:

namespace foo
{
    void print()
    {
        // 1 ...
    }
}

namespace bar
{
    namespace foo
    {
        void print()
        {
            // 2 ...
        }
    }

    using   foo::print; // refers to 2
    using ::foo::print; // refers to 1
}

then you'd see the merit of using ::. To summarize, prepending :: is a safe way to ensure that another nested namespace foo, which could be potentially added in future, will not bring you any surprises.

查看更多
登录 后发表回答