转发在C ++中声明隐藏的typedef

问题描述 投票:2回答:3

我有一个命名空间,N0,它有子命名空间,包括N1。调用代码只知道外部命名空间。我想在外部命名空间中编写一个函数,该函数返回一个std::unique_ptr<N1::T>,其结果在N0中的其他位置使用。但是,来电者不应该知道N1。我想做的是:

// N0.h
namespace N0 {
    typename T; // This isn't real C++.
    std::unique_ptr<T> foo();
    void bar(std::unique_ptr<T>&&);
}
// N0.cpp
#include "N1.h" // Get N1::T
namespace N0 {
    typedef N1::T T;
    ...
}

也就是说,我想公开一个调用者看不到的类型,但在内部我想在不同的命名空间中实际使用一个类型。这样在别处有人可以向前宣布namespace N0 { class T; }而不必知道T实际上是在N1

我可以将T本身移动到N0,但它真的属于N1

我可以用T中的虚拟类来包装N0,但这很难看,指针基本上应该这样做。

我可能会创建一个N0::T的类N1::T,但这似乎也很狡猾。

N0没有办法转发声明“我有一个类型而你不需要知道它是什么”并且该类型实际上是在不同的命名空间中吗?换句话说:为什么class C; class C{};合法,但class C; typedef int C;是非法的? (同样class C; using C = int;typedef C; typedef int C;。)它们对我来说似乎基本相同,我想不出一个聪明的模板技巧来解决它。我能想到的唯一区别是typedef版本不受Koenig查询的影响。

c++ namespaces forward-declaration
3个回答
0
投票

我的意思是你可以这样做:

// N0.h
namespace N0 {
    std::unique_ptr<T> foo();
    void bar(std::unique_ptr<T>&&);
}
// N0.cpp
namespace N0 {
    typedef N1::T t;
}

#include "N0.h"

namespace N0 {
    // whatever...
}

0
投票

在您描述的情况下,foo应该作为模板函数实现:

namespace N0 {
    template <typename T>
    std::unique_ptr<T> foo(){...};

    template <typename T>
    void bar(std::unique_ptr<T>&&){...};
}

你应该使用wrap / overload函数来做最后的技巧:

namespace N0 {
std::unique_ptr<N1::T> foo() { return foo<N1::T>(); }
//for bar there is no need to wrap, cause the T could be resolved by parameters.
}

0
投票

这是我提出的最好的,这似乎有效。我仍然觉得应该有办法不使用“技巧”使N1::T完全隐藏在呼叫者之外:

// N0.h
#pragma once
#include <memory>

namespace N0 {
    struct OpaqueObject { virtual ~OpaqueObject() {} };
    std::unique_ptr<OpaqueObject> foo();
    void bar(std::unique_ptr<OpaqueObject>&&);
}
//N0.cpp
#include "N1.h"

namespace N0 {
   std::unique_ptr<OpaqueObject> foo() { return std::unique_ptr<N1::T>(new N1::T()); }
   void bar(std::unique_ptr<OpaqueObject> &&) {}
}
// N1.h
#pragma once
#include "N0.h"

namespace N1 {
  class T : public N0::OpaqueObject {};
}
// test.cpp
#include "N0.h"

int main() {
  auto x = N0::foo();
  N0::bar(std::move(x));
}
© www.soinside.com 2019 - 2024. All rights reserved.