如何在不重复此代码的情况下将一些代码放入多个名称空间?

时间:2013-12-30 09:21:16

标签: c++ namespaces code-duplication

假设我在两个不同的命名空间中定义了方法:

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

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

foo::print()bar::print()函数绝对相等。我的项目使用了这些函数的大量调用。

有没有办法删除其中一个print()定义而不更改这些功能的调用?我的意思是以下内容(当然,C ++语言不允许这种结构,它只是一个例子):

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

如果无法按我的意思重构代码,请告诉我,您是否喜欢以下决定?如果您的项目包含此类代码,您会感到高兴吗? :)

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

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

添加

谢谢你们,我对你们的答案非常满意。我想让你澄清一下:using ::foo::printusing foo::print之间有区别吗?

5 个答案:

答案 0 :(得分:18)

您可以使用using声明来实现此目的。

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

namespace bar
{
    using foo::print;
}

修改

关于::foo::printfoo::print之间的区别:在限定名称前加上::表示您明确引用全局名称空间中的名称。这可用于选择全局的,即使在范围内有更多具有相同名称的项目。

答案 1 :(得分:14)

using声明如何:

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

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

使用::foo::print代替foo::print是重要的一点。如果您在foo内有另一个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
}

然后你会看到使用::的优点。总而言之,预先::是一种安全的方法,可以确保将来可能添加的另一个嵌套命名空间foo不会给您带来任何意外。

答案 2 :(得分:4)

使用using声明:

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

答案 3 :(得分:0)

可能最好的解决方案是:

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

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

但是你可以写:

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

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

这不是建议,但没有邪恶。编译器足够聪明,可以理解这两个函数是相同的,并且可以使用相同的汇编代码。

请记住,namespace关键字适用于程序员,编译器并不关心它们,因为编译器命名空间就像函数/方法/类的前缀。

答案 4 :(得分:-2)

<强>示例

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
    }
}