首页 > 解决方案 > 如何在两个不同的命名空间中具有相同的标头定义(但只编写一次),并具有不同的命名空间实现?

问题描述

假设我的程序由两个组件组成trusteduntrusted。我只想在两个不同的命名空间中对 A 类的声明进行一次编码,但是它们的实现可以根据命名空间而有所不同,只需对公共 API 编码一次。我不想将宏用于#ifdef UNTRSUTED.etc 等实现。

我不想使用抽象和继承来实现不同的行为。我只是好奇这是否可能。

在标题中啊,我会有

// 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命名空间)

标签: c++namespaces

解决方案


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

A_detail.h:

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

啊:

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

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

没有预处理器的帮助就没有办法做到这一点,因为每个声明(只有一个声明器)在一个范围内声明了一个名称。


推荐阅读