查找名称空间的重载解析 [英] Overload resolution looking into namespaces

查看:62
本文介绍了查找名称空间的重载解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码按预期失败,因为未找到 get 的重载.使用 std :: get 可以解决问题.

The following code fails as expected, because no overload of get is found. Using std::getwould solve the problem.

#include <array>

int main()
{
    std::array<int, 2> ar{2,3};
    auto r = get<0>(ar);//fails, get was not declared in this scope
}

但是,引入了 get 的模板版本,即使它与函数调用不匹配,也使编译器使用了 std :: get 版本:

However, introducing a templated version of get, even though it's not matching the function call, somehow makes the compiler use the std::get version:

#include <array>

template <typename T>
void get(){};

int main()
{
    std::array<int, 2> ar{2,3};

    auto r = get<0>(ar);//returns 2
}

我找不到解释这一点的标准的任何部分.这是我测试过的所有3个编译器中的一个bug(可能不是),还是我缺少某些东西?

I can't find any part of the standard that explains this. Is this a bug in all 3 compilers I tested (probably not), or am I missing something?

此行为已在

  • MSVC 15.9.2
  • C 8.0.0
  • GCC 9.0.0(仍为实验版)

我知道ADL.但是,如果ADL使第二个代码起作用,那么为什么在第一部分中却没有呢?

I am aware of ADL. But if ADL makes the second code work, why does it not in the first part?

推荐答案

当涉及显式模板参数时,除非在调用点引入模板函数声明,否则不使用ADL.您正在使用非限定形式的 get 和非类型模板参数 0 ,因此您需要引入模板函数声明或使用合格版本的get 作为 std :: get< 0>(ar).

ADL is not used when explicit template arguments are involved unless you introduce a template function declaration at the call point. You're using an unqualified form of get using a non-type template argument 0, so you need to introduce a template function declaration or use the qualified version of get as std::get<0>(ar).

以标准语言 [temp.arg.explicit]/8 :(强调我的意思)

In standardese [temp.arg.explicit]/8: (emphasis mine)

[注意:对于简单的函数名称,即使在调用范围内看不到函数名称,也要使用基于参数的查找(6.4.2).这是因为该调用仍然具有函数调用(6.4.1)的语法形式.但是,当使用带有显式模板参数的函数模板时,调用将没有正确的语法形式,除非在调用时有一个名称可见的函数模板.如果看不到这样的名称,则该调用的语法格式不正确,并且依赖于参数的查找也不适用.如果某些此类名称可见,则将应用依赖于参数的查找,并且可能在其他名称空间中找到其他功能模板.

[ Note: For simple function names, argument dependent lookup (6.4.2) applies even when the function name is not visible within the scope of the call. This is because the call still has the syntactic form of a function call (6.4.1). But when a function template with explicit template arguments is used, the call does not have the correct syntactic form unless there is a function template with that name visible at the point of the call. If no such name is visible, the call is not syntactically well-formed and argument-dependent lookup does not apply. If some such name is visible, argument dependent lookup applies and additional function templates may be found in other namespaces.

正如@Yakk-Adam Nevraumont在评论中指出的,如果不存在模板函数声明,则表达式 get< 0>(ar)将被解析为(get<; 0)>(ar),即作为比较表达式的系列而不是函数调用.

As @Yakk - Adam Nevraumont has pointed out in the comment, without the presence of the template function declaration, the expression get<0>(ar) will be parsed as (get<0)>(ar), i.e as a serie of comparison expressions instead of a function call.

这篇关于查找名称空间的重载解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆