提问人:radio32145 提问时间:10/18/2023 最后编辑:user12002570radio32145 更新时间:10/19/2023 访问量:109
在命名空间上下文中定义成员 C++ 类模板,其模板参数在包含模板声明的类中是私有的
defining a member C++ class template in namespace context with a template parameter that is private in the class containing the template declaration
问:
我想在命名空间上下文中定义一个成员 C++ 类模板。成员类模板和该模板的参数使用的类型在包含成员模板的类中声明为私有。编译器会抱怨,因为模板参数的类型被声明为私有。
当我使用 g++ (GCC) 13.2.0 在文件 temp.cc 中编译以下代码时
// the following class definition would go in its own header file
class A {
public: // I don't want to declare struct S public
private:
struct N;
template<const N* K> struct S; // I don't want to define struct S here!
};
// the following definition would go in a separate file
template<const A::N* K> struct A::S {
};
我收到以下错误
g++ temp.cc
temp.cc:9:19: error: ‘struct A::N’ is private within this context
9 | template<const A::N* K> struct A::S {
| ^
temp.cc:5:10: note: declared private here
5 | struct N;
| ^
有没有办法在不声明公开的情况下安抚编译器?struct N
请注意,在编译的私有范围内定义就可以了struct N
class A
class A {
public:
private:
struct N;
template<const N* K> struct S {}; // no compilation error!
};
因此,问题在于编译器的行为似乎不一致:当在 的作用域中定义时,允许将其用作模板参数,但在命名空间作用域中定义时不允许使用。为什么不呢?struct A::S
struct N*
struct A::S
class A
答:
1赞
Thomas
10/18/2023
#1
在您提供的代码中,您声明了一个名为 outside 的新结构。要表明您是在其中定义私有结构而不是新结构,您需要更改为(注意要添加的)。S
A
A
template<const A::N* K> struct S {};
template<const A::N* K> struct A::S {};
A::
0赞
Haiyu Zhu
10/18/2023
#2
在另一个文件中定义,您可能会遇到链接错误。
我认为您可以使用代理模式,公开 API 并在内部隐藏数据结构。
根据您的示例,所有代码都可以是:S
在文件中(公共标头)A.h
class A {
public:
Foos();
private:
A();
};
A *MakeA();
in(内部标头)A_Proxy.h
include 'A.h'
class AProxy : public A {
private:
struct N;
template<const N* K> struct S{}; // decl the S here
};
A *MakeA() {
return new AProxy();
}
0赞
user12002570
10/18/2023
#3
首先,在外部定义结构时,您没有使用封闭类对其进行限定。要解决此问题,只需添加以使用封闭类进行限定即可。S
A::
S
这似乎是一个 gcc 错误。clang 和 msvc 都接受该程序。
class A {
struct N;
template<const N* K> struct S;
};
// works now
class A::N{};
template<const A::N* K> class A::S{};//gcc rejects this but clang and msbc accepts this
评论
0赞
radio32145
10/19/2023
我编辑了我的问题以解决您注意到的第一个问题。我问题的重点是,我不想声明和作为 .struct N
struct S
class A
0赞
user12002570
10/19/2023
@radio32145 这似乎是一个 gcc 错误。请参阅更新后的答案。
评论
struct S {
==>struct A::S {
public
private
A
S
private