【发布时间】:2011-07-17 20:59:32
【问题描述】:
考虑以下程序:
#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 草案选择哪个重载是正确的重载?
【问题讨论】:
-
我尝试阅读最新的 C++0x 草案 N3242 的第 13 条(“重载”),但这让我很头疼。
-
我很确定 gcc 做错了。即使所有三个候选者都是模板,gcc 仍然更喜欢转换为指针而不是完全匹配的数组引用。 ideone.com/7UXag
-
@Ben:在阅读第 13 条之前,我会同意你的看法:在表格中,数组到指针的转换被列为精确匹配,这意味着 (2) 是在这里正确选择,因为 (3) 是一个模板,但这也意味着在您的示例中,所有三个重载都是模板,至少 (2) 和 (3) 之间应该有歧义。 :-(
-
不是答案,但我认为 (2) 是完全匹配的,不是吗?
-
@James:这甚至不是正确的部分,AFAICT。由于其中一个候选函数是模板函数,因此第 14.8.3 节进行管理。
标签: c++ arrays reference c++11 overload-resolution