- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
考虑以下程序:
#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
?为什么?
三个编译器的最新发布版本对这个问题的答案存在分歧:
重载决议规则在不同的 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 的最后一个项目符号获得诊断,因为 T1
和 T2
与引用相关。如果我们假设第 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/
假设我有一个类,我在其中重载了运算符 == : Class A { ... public: bool operator== (const A &rhs) const; ... };
我知道你不应该使用 std::find(some_map.begin(), some_map.end()) 或 std::lower_bound,因为它会采用线性时间而不是 some_map.lowe
我正在尝试在 Haskell 中定义 Vector3 数据类型,并允许在其上使用 (+) 运算符。我尝试了以下方法: data Vector3 = Vector3 Double Double Doub
我已经为我的类图将运算符重载为“-”。它的用途并不完全直观(糟糕的编码 - 我知道)但是如果我做 graph3 = graph2-graph1 那么图 3 是应该只接收图 2 和图 1 中的那些顶点。
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Operator overloading 我想重载 以按字母顺序排列字符串,但我不确定该怎么做。 如何再次
下面的代码给我一个编译错误。谁能告诉我为什么? class mytype { public: int value; mytype(int a) { value = a;
这有什么问题吗? class Vec2 attr_accessor :x, :y # ... def += (v) @x += v.x @y += v.y retu
是否可以重载 [] 运算符两次?允许这样的事情:function[3][3](就像在二维数组中一样)。 如果可能的话,我想看看一些示例代码。 最佳答案 您可以重载 operator[] 以返回一个对象
我的团队目前正在与 Lua 合作,创建一个 android 游戏。我们遇到的一件事是表面上无法创建重载构造函数。 我习惯于使用默认值设置一个对象,然后在需要时使其过载。 前任: apples() {
我有一个网页,在某个时候显示一个导航栏,它只不过是一个 a 元素的列表 (ul)。所述 a 元素的大多数样式规则都是通用的。唯一应该改变的部分是要显示的图像,可以从列表中每个 li 元素的 id 标签
我对使用/重载“范围步长”运算符(.. ..)很感兴趣,但我终其一生都无法了解如何使用它。 在文档中它说 // Usage: start .. step .. finish 但是在 F# shell
Java 11(可能无关紧要): public static String toString(Object obj) { return ReflectionToStringBuilder.to
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我无法理解以下代码(针对行号进行注释) class Base { void m1(Object o) { } void m2(String o) { } } publi
我有以下代码片段: #include using namespace std; struct Integer{ int x; Integer(const int val) : x(v
class myclass{ //definitions here }; myclass e; int myarray[10]; /* Do something... */ e = myarray;
为什么不能将下标运算符(operator [])作为 friend 函数重载? 最佳答案 正如Bjarne Stroustrup在D&E book中所说: However, even in the o
我有以下代码片段: #include using namespace std; struct Integer{ int x; Integer(const int val) : x(v
因此,我有一个问题是我最近尝试重载 namespace Eng { /** * A structure to represent pixels */ typedef
如何重载onResume()以正确的方式工作?我想从 activity 返回到 MainActivity ,我希望在其中具有与应用程序启动后相同的状态。我想使用 recreate() 但它循环了或者类
我是一名优秀的程序员,十分优秀!