gpt4 book ai didi

c++ - 重载分辨率和数组 : which function should be called?

转载 作者:IT老高 更新时间:2023-10-28 12:46:10 24 4
gpt4 key购买 nike

考虑以下程序:

#include <cstddef>
#include <cstdio>

void f(char const*&&) { std::puts("char const*&&"); } // (1)
void f(char const* const&) { std::puts("char const* const&"); } // (2)

template <std::size_t N>
void f(char const (&)[N]) { std::puts("char const(&)[N]"); } // (3)

int main()
{
const char data[] = "a";
f(data);
}

应该调用哪个f?为什么?

三个编译器的最新发布版本对这个问题的答案存在分歧:

  • (1) 在使用 g++ 4.5.2
  • 编译程序时调用
  • (2) 在使用 Visual C++ 2010 SP1
  • 编译程序时调用
  • (3) 在使用 Clang 3.0 (trunk 127530)
  • 编译程序时调用

重载决议规则在不同的 C++0x 草案中是否发生了重大变化?或者,这些编译器中的两个真的完全错误吗?根据最新的 C++0x 草案选择哪个重载是正确的重载?

最佳答案

首先,所有三个的转换序列是相同的,除了前两个,有一个左值转换(左值到右值转换),但是在排序转换序列中不使用它。这三个都是完全匹配的(函数模板特化具有参数类型char const(&)[2])。

如果您在 13.3.3.2p3 处迭代规则,则在本段停止

S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference.

如果需要将右值引用绑定(bind)到左值,则无法形成转换序列,规范在 13.3.3.1.4p3 中说。如果您查看 8.5.3p5 最后一个项目符号的引用绑定(bind)是如何工作的,它将从数组中创建一个 char const* 类型的临时(我认为他们的意思是 rvalue 临时)左值并将引用绑定(bind)到该临时文件。因此,我认为(1) 优于(2)(1)(3) 也一样,虽然我们不需要这个,因为 (3) 是一个模板,所以可以打成平手,我们会再次选择(1)

n3225 中,他们更改了引用绑定(bind)规则,以便右值引用可以绑定(bind)到作为左值的初始化表达式,只要该引用将绑定(bind)到右值(可能通过转换初始化程序来创建)之前正确)。这可能会影响 Visual C++ 的处理,此处可能不是最新的。

我不确定clang。即使它会忽略 (1),它也会在 (2)(3) 之间打成平手,并且需要选择 (2) 因为它不是模板。


我认为 8.5.3p5 的最后一个项目符号令人困惑,因为它说“否则为临时类型......”。目前尚不清楚临时值是被 13.3.3.1.4p3 视为左值还是右值,这意味着我不确定根据规范的确切文字,以下内容应该如何真正表现

void f(int &);
void f(int &&);

int main() {
int n = 0;
f(n);
}

如果我们假设第 13 条将临时值视为右值,那么我们将右值 ref 绑定(bind)到第二个函数中的右值和第一个函数中的左值。因此,我们将选择第二个函数,然后通过 8.5.3p5 的最后一个项目符号获得诊断,因为 T1T2 与引用相关。如果我们假设第 13 条将临时值视为左值,那么以下内容将不起作用

void f(int &&);
int main() {
f(0);
}

因为我们会将右值 ref 绑定(bind)到第 13 条的左值,这将使函数不可行。如果我们将“将右值引用绑定(bind)到左值”解释为引用初始化表达式而不是绑定(bind)到的最终表达式,我们将不会接受以下内容

void f(float &&);
int main() {
int n = 0;
f(n);
}

然而,这从 n3225 开始有效。所以似乎有些困惑 - 我就此向委员会发送了 DR。

关于c++ - 重载分辨率和数组 : which function should be called?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5347444/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com