转发在C ++中声明隐藏的typedef
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了转发在C ++中声明隐藏的typedef相关的知识,希望对你有一定的参考价值。
我有一个命名空间,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查询的影响。
我的意思是你可以这样做:
// 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...
}
在您描述的情况下,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.
}
这是我提出的最好的,这似乎有效。我仍然觉得应该有办法不使用“技巧”使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));
}
以上是关于转发在C ++中声明隐藏的typedef的主要内容,如果未能解决你的问题,请参考以下文章