C++ 在C+中向前声明隐藏的typedef+;
我有一个名称空间,C++ 在C+中向前声明隐藏的typedef+;,c++,namespaces,forward-declaration,C++,Namespaces,Forward Declaration,我有一个名称空间,N0,它有子名称空间,包括N1。调用代码只知道外部名称空间。我想在外部名称空间中编写一个函数,返回一个std::unique_ptr,该结果在N0的其他地方使用。但是,调用方不应该知道N1。我想做的是: //N0.h 命名空间N0{ 这不是真正的C++。 std::unique_ptr foo(); 空心条(标准:唯一的); } //N0.cpp #包括“N1.h”//Get N1::T 命名空间N0{ N1型:T型; ... } 也就是说,我想公开一个调用方看不到的类型,
N0
,它有子名称空间,包括N1
。调用代码只知道外部名称空间。我想在外部名称空间中编写一个函数,返回一个std::unique_ptr
,该结果在N0
的其他地方使用。但是,调用方不应该知道N1
。我想做的是:
//N0.h
命名空间N0{
这不是真正的C++。
std::unique_ptr foo();
空心条(标准:唯一的);
}
//N0.cpp
#包括“N1.h”//Get N1::T
命名空间N0{
N1型:T型;
...
}
也就是说,我想公开一个调用方看不到的类型,但在内部我想实际使用另一个命名空间中的类型。这样,其他地方的人就可以直接转发声明名称空间N0{class T;}
,而不必知道T
实际上在N1
中
我可以将T
本身移动到N0
,但它确实属于N1
我可以在N0
中用一个伪类包装T
,但这很难看,指针基本上应该这样做
我可能会创建一个类N0::T
,它是N1::T
的子类,但这看起来也很讨厌
N0
是否无法转发声明“我有一个类型,您不需要知道它是什么”并使该类型实际位于不同的命名空间中?换句话说,为什么是C类;C类{}代码>合法,但<代码>C类;typedef int C代码>是非法的吗?(同样地,class C;使用C=int;
或typedef C;typedef int C;
)它们在我看来基本相同,我想不出一个聪明的模板技巧来绕过它。我能想到的唯一区别是typedef版本不需要Koenig查找。我的意思是你可以这样做:
// N0.h
namespace N0 {
std::unique_ptr<T> foo();
void bar(std::unique_ptr<T>&&);
}
在您描述的情况下,应该将foo实现为一个模板函数:
namespace N0 {
template <typename T>
std::unique_ptr<T> foo(){...};
template <typename T>
void bar(std::unique_ptr<T>&&){...};
}
名称空间N0{
模板
std::unique_ptr foo(){…};
模板
空条(std::unique_ptr&&){…};
}
您应该使用wrap/重载函数来完成最后一个技巧:
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.
}
名称空间N0{
std::unique_ptr foo(){return foo();}
//对于棒材,无需缠绕,因为T可以通过参数解决。
}
这是我想到的最好的,似乎很管用。我仍然觉得应该有一种方法可以避免使用“技巧”使N1::T
对呼叫者完全隐藏:
//N0.h
#布拉格语一次
#包括
命名空间N0{
结构OpaqueObject{virtual~OpaqueObject(){};
std::unique_ptr foo();
空心条(标准:唯一的);
}
//N0.cpp
#包括“N1.h”
命名空间N0{
std::unique_ptr foo(){返回std::unique_ptr(新的N1::T());}
空条(std::unique_ptr&&{}
}
//N1.h
#布拉格语一次
#包括“N0.h”
名称空间N1{
类T:公共N0::OpaqueObject{};
}
//test.cpp
#包括“N0.h”
int main(){
自动x=N0::foo();
N0::bar(std::move(x));
}
我不这么认为。我只希望N0
能够公开地说“我有一个类型T
”,你可以用指针指向它,然后私下里让N0
定义它“实际上,当我说T
时,我的意思是N1::T
。继承可能是一个我不遵循的选项。在N0.h
中,T
从何而来?@Ben不知从何而来。好的,这里的技巧是在已经定义了N0::T
之后包含它,这样头中的代码就变得有效了。它基本上是这样的,中间的名称空间就是你的头中的名称空间。但是foo()
的调用者呢?如果您不指定要使用哪个T
,并且只能对单个T
使用它,则它们将#包括“N0.h”
并获得“未声明的标识符”T`对吗?@Ben Jup