为什么 ADL 找不到函数模板?
C++ 规范的哪一部分限制参数相关查找在关联命名空间集中查找函数模板?换句话说,为什么下面main
中的最后一个调用无法编译?
namespace ns {
struct foo {};
template<int i> void frob(foo const&) {}
void non_template(foo const&) {}
}
int main() {
ns::foo f;
non_template(f); // This is fine.
frob<0>(f); // This is not.
}
What part of the C++ specification restricts argument dependent lookup from finding function templates in the set of associated namespaces? In other words, why does the last call in main
below fail to compile?
namespace ns {
struct foo {};
template<int i> void frob(foo const&) {}
void non_template(foo const&) {}
}
int main() {
ns::foo f;
non_template(f); // This is fine.
frob<0>(f); // This is not.
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这部分解释一下:
C++ Standard 03 14.8.1.6:
This part explains it:
C++ Standard 03 14.8.1.6:
从 c++20 开始,adl 也可以与显式函数模板配合使用。这是建议:
P0846R0:不可见的 ADL 和函数模板< /a>:
目前,只有 GCC 9 实现了此功能,因此您的示例可以编译。
现场演示
。Since c++20, adl works also fine with explicit function template. Here is the proposal:
P0846R0: ADL and Function Templates that are not Visible:
Currently, only GCC 9 has implement this feature, so your example can compile.
live demo
.我想改进稍微接受的答案。 OP问题中尚不清楚,但标准中的重要部分(由Kornel引用)是这样的(强调我的):
因此禁止依赖 ADL 并使用显式模板参数。不幸的是,使用非类型模板参数需要使用显式参数(除非它们有默认值)。
下面是显示这一点的示例代码:
[live]
I would like to refine slightly accepted answer. It is not clear in the OP question, but the important part from the standard (cited by Kornel) is this (emphasis mine):
so what is prohibited is relying on ADL and using explicit template arguments. Unfortunately using non-type template arguments requires using explicit arguments (unless they have default values).
Below is sample code showing this.:
[live]
编辑:不,这是不对的。请参阅@Kornel 的回答。
我不完全确定,但在查阅了 Stroustrup 的“C++ 编程语言”后,我认为附录 C 第 13.8.4 节可能是原因。
由于
frob
是一个模板,因此可以想象在调用它之后的某个时刻将其专门化为i=0
。这意味着实现将留下两种可能的方式来选择调用哪个frob
,因为它似乎可以在实例化时或在处理结束时选择它翻译单位。所以,我认为问题是你可以做
Edit: No, this is not right. See @Kornel's answer.
I'm not entirely sure but having consulted Stroustrup's "The C++ programming language" I think that Appendix C section 13.8.4 might be the cause.
Since
frob
is a template one could conceivably specialise it fori=0
at a point after you call it. This means that the implementation would be left with two possible ways of choosing whichfrob
to call as it appears it can choose it at the point of instantiation or at the end of processing the translation unit.So, I think the problem is you could do