Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中向前声明隐藏的typedef+;_C++_Namespaces_Forward Declaration - Fatal编程技术网

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