struct Foo {};
struct Bar {};
int Baz(const Foo&) { return 0; }
int Baz(Bar&&) { return 1; }
int main()
{
return Baz({});
}
这个电话含糊不清吗?MSVC选择右值引用重载。GCC表示这是不明确的。Clang也选择右值引用,但如果它是intbaz(std::vector),则不再选择
{}
到Bar
是标准的转换序列吗?
有人能解释一下为什么这一点适用或不适用:
[...]
c)或者,如果不是这样,S1和S2都绑定到引用参数,而不是ref限定成员函数的隐式对象参数,并且S1绑定右值引用到右值,而S2绑定左值引用到右值
(https://en.cppreference.com/w/cpp/language/overload_resolution)
正如问题中已经提到的,标准在[over.ics.rank]/(3.2)中说:
标准转换顺序S1
比标准转换顺序S2
更好
...
S1
和S2
是引用绑定(11.6.3),两者都不引用没有ref-限定符声明的非静态成员函数的隐式对象参数,并且S1
将右值引用绑定到右值,S2
绑定左值引用...
所以GCC在这里是错误的。
实际上,通过在结构中添加默认构造函数,Clang也会受到类似的欺骗:
struct Foo {
constexpr Foo() = default;
};
struct Bar {
constexpr Bar() = default;
};
constexpr int Baz(const Foo&) { return 0; }
constexpr int Baz(Bar&&) { return 1; }
int main() {
static_assert( Baz({}) == 1 );
}
MSVC是正确选择Baz(Bar)的编译器
这两个函数完全匹配。以下是该标准的引用: 标准转换序列S1是比标准转换序列S2更好的转换序列,如果 ... S1和S2是引用绑定(8.5.3),都不引用未使用ref限定符声明的非静态成员函数的隐式对象参数,S1将右值引用绑定到右值,S2将左值引用绑定。 这不意味着第二个更好吗? 更新: 有一个相关的问题。下面的代码是它的简化版本。
考虑以下C 11代码: 这会产生一个错误: 我明白为什么,但我正试图从标准中的语言来证明这一点。 意译C 11 N34858.5.3.5: int的引用由int类型的表达式初始化,如下所示:(yes) 如果引用是右值引用:(是) 如果初始值设定项表达式:(是) 是xvalue、类prvalue、数组prvalue还是函数左值(否?),或 这两点都不适用吗?所以我们应该假设它是不正确的,因为两者都不
我通过解决一些黑客等级问题来学习java。下面的代码是关于学习静态初始值设定项块的。例外情况是thown和Capture,但程序仍在运行,我不确定原因。 输入:-1,2 预期输出:java.lang.例外:宽度和高度必须为正 实际输出:宽度和高度必须为正-2
我对Swift类有一个问题。我有UITableViewController类和UITableViewCell类的swift文件。我的问题是UITableViewCell类和网点。这个类有一个错误Class“HomeCell”没有初始化程序,我不明白这个问题。 感谢您的回复。
我相信现代C初始值设定项列表对于初始化对象非常有用,甚至不需要定义自己的构造函数: 但是,当我的类从另一个类继承时,这不起作用: 我尝试添加
Ivor Horton在开始的Visual C 2013中提到了C语言中的“初始化列表”: "对于const或引用类型的类成员,您无法选择如何初始化它们。唯一的方法是在构造函数中使用成员初始化器列表。构造函数主体内的赋值将不起作用。" 我的Visual Studio 2012 express没有编译初始值设定项列表,所以一开始我很困惑,然后我意识到它不受支持。 我的问题是人们如何在初始化器列表之前