在变量前添加 : 会给出错误的结果
Adding the : in front of variable gives wrong result
我比较的是class。对于下面的代码
#include <string>
#include <set>
#include <tuple>
#include <cassert>
enum class e : bool
{
positive = true,
negetive = false
};
class A
{
public:
int a;
e e1 : 1;
friend bool operator==(const A&, const A&);
};
bool operator==(const A& lhs, const A& rhs) {
auto tie = [](const A& a1) {
return std::tie(a1.a, a1.e1);
};
auto x1 = tie(lhs);
auto x2 = tie(rhs);
return x1 == x2;
}
int main()
{
A a1;
a1.a = 10;
a1.e1 = e::positive;
A b1;
b1.a = 10;
b1.e1 = e::positive;
assert(a1 == b1);
}
输出为:
a.out: main.cpp:44: int main(): Assertion `a1 == b1' failed.
这是错误的,因为其中两个 class 是相同的。
但是,如果我将代码行从 e e1 : 1;
更改为 e e1;
,它会给出正确的结果。
首先我想知道 : 在这种情况下是做什么的?
为什么加上这个结果不对?
可以看到代码here.
提前致谢。
这个函数:
auto tie = [](const A& a1) {
return std::tie(a1.a, a1.e1);
};
return一个std::tuple<int const&, e const &>
。尽管 tuple
存储的字段是引用,但对于位字段有一个特殊规则,即创建位字段的临时副本,并且引用绑定到该临时副本。这意味着当您从函数中 return 时,对位字段的引用是悬空的,导致您稍后使用 tuple
的该字段时出现未定义的行为。
您可以通过显式指定 return 类型来解决此问题:
auto tie = [](const A& a1) -> std::tuple<int, e> {
return std::tie(a1.a, a1.e1);
};
这里是 demo。
或者,您可以 return 衰减参数类型并避免悬空问题的 tuple
,如下所示:
auto tie = [](const A& a1) {
return std::make_tuple(a1.a, a1.e1);
};
我比较的是class。对于下面的代码
#include <string>
#include <set>
#include <tuple>
#include <cassert>
enum class e : bool
{
positive = true,
negetive = false
};
class A
{
public:
int a;
e e1 : 1;
friend bool operator==(const A&, const A&);
};
bool operator==(const A& lhs, const A& rhs) {
auto tie = [](const A& a1) {
return std::tie(a1.a, a1.e1);
};
auto x1 = tie(lhs);
auto x2 = tie(rhs);
return x1 == x2;
}
int main()
{
A a1;
a1.a = 10;
a1.e1 = e::positive;
A b1;
b1.a = 10;
b1.e1 = e::positive;
assert(a1 == b1);
}
输出为:
a.out: main.cpp:44: int main(): Assertion `a1 == b1' failed.
这是错误的,因为其中两个 class 是相同的。
但是,如果我将代码行从 e e1 : 1;
更改为 e e1;
,它会给出正确的结果。
首先我想知道 : 在这种情况下是做什么的? 为什么加上这个结果不对?
可以看到代码here.
提前致谢。
这个函数:
auto tie = [](const A& a1) {
return std::tie(a1.a, a1.e1);
};
return一个std::tuple<int const&, e const &>
。尽管 tuple
存储的字段是引用,但对于位字段有一个特殊规则,即创建位字段的临时副本,并且引用绑定到该临时副本。这意味着当您从函数中 return 时,对位字段的引用是悬空的,导致您稍后使用 tuple
的该字段时出现未定义的行为。
您可以通过显式指定 return 类型来解决此问题:
auto tie = [](const A& a1) -> std::tuple<int, e> {
return std::tie(a1.a, a1.e1);
};
这里是 demo。
或者,您可以 return 衰减参数类型并避免悬空问题的 tuple
,如下所示:
auto tie = [](const A& a1) {
return std::make_tuple(a1.a, a1.e1);
};