为什么 GCC 允许私有嵌套模板类/结构在全局模板函数中可见?
我不明白为什么在下面的代码中,我可以创建函数 print_private_template
而编译器却抱怨 print_private_class
:
#include <cstdio>
class A
{
private:
template <unsigned T>
struct B
{
};
struct C
{
};
public:
template <unsigned T>
B<T> getAb()
{
return B<T>();
}
C getAc()
{
return C();
}
};
template<unsigned T>
void print_private_template(const A::B<T> &ab)
{
printf("%d\n", T);
}
void print_private_class(const A::C &ac)
{
printf("something\n");
}
int main(int, char**)
{
A a;
print_private_template(a.getAb<42>());
print_private_class(a.getAc());
return 0;
}
这是预期的行为吗?编译器错误/扩展?
需要明确的是,我的目标是使编译器在使用 print_private_template
和 print_private_class
时都出现错误。
I don't understand why in the following code, I am allowed to create the function print_private_template
while the compiler complains about print_private_class
:
#include <cstdio>
class A
{
private:
template <unsigned T>
struct B
{
};
struct C
{
};
public:
template <unsigned T>
B<T> getAb()
{
return B<T>();
}
C getAc()
{
return C();
}
};
template<unsigned T>
void print_private_template(const A::B<T> &ab)
{
printf("%d\n", T);
}
void print_private_class(const A::C &ac)
{
printf("something\n");
}
int main(int, char**)
{
A a;
print_private_template(a.getAb<42>());
print_private_class(a.getAc());
return 0;
}
Is this an expected behaviour? a compiler bug/extension?
Just to be clear, my goal is to make the compiler error on both the usage of print_private_template
and print_private_class
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Comeau 确实给出了一个错误(当您注释掉
print_private_class
函数及其在严格的 C++03 模式下调用。G++ 4.5 不会报告
-std=c++ -Wall -pedantic
的任何错误。您的类
A::C
和类模板A::B
都具有与任何其他普通成员相同的可见性。因此,print_private_class
和print_private_template
都需要诊断。Comeau does give an error (when you comment out the
print_private_class
function and its call in strict C++03 mode.G++ 4.5 on Windows does not report any error with
-std=c++ -Wall -pedantic
though.Your class
A::C
and class templateA::B<T>
both have the same visibility as any other normal members. Hence, bothprint_private_class
andprint_private_template
require a diagnostic.正如 Dirk Gently 所说,GCC 在实例化嵌套在其他(模板)结构/类中的模板结构/类时不执行访问控制。
解决此问题的一种方法是将它们封装在非模板结构中:
最后一行将无法编译并出现错误:
我承认这很丑陋,尤其是必须使用 PT::template 但它似乎可以有效地防止客户端实例化他们不打算访问的帮助程序模板,因此值得一试。
As stated by Dirk Gently, GCC doesn't perform access control when instantiating template structs / classes nested in other (template) structs / classes.
One way to work around this is to encapsulate them in a non-template struct:
The last line will fail to compile with the error:
I'll grant that this is ugly, especially having to use
PT::template
but it seems to effectively prevent clients from instantiating helper templates they aren't meant to access, so it's worth a shot.它在 GCC 11 中得到了修复
十年后...并且该错误在 GCC 11 中得到了修复:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41437#c13(欺骗池中的另一个点之前已链接到阴暗地)。
最小重现:
main.cpp
仍然可以在 GCC 10.2 中编译,并启用所有警告:
但在
clang++
10 中正确失败:以上在 GCC 中失败,因为
f
是一个模板功能。It got fixed for GCC 11
Ten years later... and the bug got fixed for GCC 11: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41437#c13 (another point in the dupe pool had been previously linked to by dirkgently).
A minimal reproduction:
main.cpp
still compiles in GCC 10.2 with all warnings enabled:
but fails correctly in
clang++
10:The above fails to fail in GCC because
f
is a template function.