如何在两个不同的名称空间(但只编写一次)中具有相同的标头定义,并使用不同的名称空间实现?

时间:2019-09-26 23:38:22

标签: c++ namespaces

比方说,我的程序由两个组成部分组成:受信任不受信任。我只想在两个不同的命名空间中对A类的声明进行一次编码,但是基于命名空间,它们的实现可以有所不同,只对通用API进行一次编码。我不想将宏用于#ifdef UNTRSUTED等。

我不想使用抽象和继承来实现不同的行为。我只是想知道是否有可能。

在标题A.h中,我将拥有

// A.h
#pragma once
namespace app {
 // I know I can't get what I want with naming the same namespace twice
 namespace untrusted, trusted {
  class A {
    doDifferentFoo();
    doCommonBar() // this one is common between two impls;
  }
 }
}

在实现中,我将拥有A-common.cpp(仅对两个命名空间实现一次通用接口),A-untrusted.cpp(对不可信命名空间实现doDifferentFoo)和A-trusted.cpp(实现doDifferentFoo(用于可信名称空间)

2 个答案:

答案 0 :(得分:1)

我想最简单的方法是将公共声明移到一个额外的文件中,然后将其包含两次:

A_detail.h:

// No `#pragma once` here!
class A {
    doDifferentFoo();
    doCommonBar(); // this one is common between two impls;
};

A.h:

#pragma once
namespace app {
    namespace trusted {
        #include "a_detail.h"
    }
    namespace untrusted {
        #include "a_detail.h"
    }
}

A-untrusted.cpp:

#include "a.h"
namespace app { namespace untrusted {
    // ...
} }

A-trusted.cpp:

#include "a.h"
namespace app { namespace trusted {
    // ...
} }

A-common_detail.cpp(也许选择其他文件结尾;不应编译为翻译单元):

// common definitions/declarations without `namespace`

A-common.cpp:

namespace app {
    namespace untrusted {
        #include "A-common_detail.cpp"
    }
    namespace trusted {
        #include "A-common_detail.cpp"
    }
}

我不确定这是否值得。或者,您可以(在具有通用代码的每个文件中)为所有通用代码使用宏,并为两个名称空间调用两次。但是,您确实说过您不想使用宏。

没有预处理器就无法做到这一点,因为每个声明(只有一个声明器)在一个作用域中恰好声明一个名称。

答案 1 :(得分:0)

// A.h

class A {
    void doDifferentFoo();

    void doCommonBar()
    { // ...
    }

};

// A_trusted.h

namespace app
{
namespace trusted
{
#include "A.h"

void A::doDifferentFoo() // can be moved to cpp-file if needed/wanted
{
}

}
}

// A_untrusted.h

namespace app
{
namespace untrusted
{
#include "A.h"

void A::doDifferentFoo() // can be moved to cpp-file if needed/wanted
{
}

}        
}