我想在命名空间上下文中定义一个成员C类模板。成员类模板和该模板的参数使用的类型在包含成员模板的类中声明为私有。编译器会抱怨,因为模板参数的类型被声明为private。
当我使用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
是公共的?
注意,在class A
的私有作用域中 * 定义 * struct N
可以很好地编译
class A {
public:
private:
struct N;
template<const N* K> struct S {}; // no compilation error!
};
因此,问题是编译器的行为似乎不一致:当在class A
的作用域中定义struct A::S
时,struct A::S
可以使用struct N*
作为模板参数,但当在namespace作用域中定义时则不行。为什么不呢?
3条答案
按热度按时间68de4m5k1#
在你给出的代码中,你在
A
之外声明了一个名为S
的新结构。为了表明您正在A
中定义私有结构体而不是新结构体,您需要将template<const A::N* K> struct S {};
更改为template<const A::N* K> struct A::S {};
(注意添加的A::
)。wbgh16ku2#
在另一个文件中定义
S
,可能会遇到链接错误。我认为您可以使用代理模式,公开API并在内部隐藏数据结构。举个例子,所有的代码都可以是:在
A.h
文件中(公共头)in
A_Proxy.h
(内部标题)mum43rcc3#
首先,当在外部定义结构
S
时,你没有用 * 封闭类 * 来**限定它。要解决这个问题,只需添加A::
,使S
由封闭类限定。这似乎是一个gcc bug。clang和msvc都接受这个程序。
GCC rejects out of class definition of inner private class template