如何解决自动从派生类转换为基类成员变量的类型
长话短说:我想了解为什么下面的代码的最后一行没有使用D::operator B() const
转换运算符,因此在使用g++ -std=c++17 source.cpp
进行编译(使用{{ 1}}成功了。)
错误是:
g++ -std=c++2a deleteme.cpp
代码是:
$ g++ -std=c++17 deleteme.cpp && ./a.out
In file included from /usr/include/c++/10.2.0/cassert:44,from deleteme.cpp:1:
deleteme.cpp: In function ‘int main()’:
deleteme.cpp:19:14: error: no match for ‘operator==’ (operand types are ‘D’ and ‘B’)
19 | assert(d == B{2}); // conversion operator not invoked explicitly errors // LINE
| ~ ^~ ~~~~
| | |
| D B
In file included from /usr/include/c++/10.2.0/utility:70,from deleteme.cpp:2:
/usr/include/c++/10.2.0/bits/stl_pair.h:466:5: note: candidate: ‘template<class _T1,class _T2> constexpr bool std::operator==(const std::pair<_T1,_T2>&,const std::pair<_T1,_T2>&)’
466 | operator==(const pair<_T1,_T2>& __x,const pair<_T1,_T2>& __y)
| ^~~~~~~~
/usr/include/c++/10.2.0/bits/stl_pair.h:466:5: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/10.2.0/cassert:44,from deleteme.cpp:1:
deleteme.cpp:19:20: note: ‘B’ is not derived from ‘const std::pair<_T1,_T2>’
19 | assert(d == B{2}); // conversion operator not invoked explicitly errors // LINE
|
这个问题是对this的跟进。在那里,我得到了帮助,编写了一个类#include <cassert>
#include <utility>
struct B {
int x;
B(int x) : x(x) {}
bool operator==(B const& other) const { return x == other.x; }
};
struct D : std::pair<B,char*> {
operator B() const { return this->first; }
};
int main() {
B b{1};
D d{std::pair<B,char*>(B{2},(char*)"hello")};
assert((B)d == B{2}); // conversion operator invoked explicitly is fine
assert(d == B{2}); // conversion operator not invoked explicitly errors // LINE
}
,该类的行为类似于一对(因此继承自该类),其Recursive
是first
,第二个是std::array
(请参见链接以获取详细信息。
由于boost::hana::optional<std::vector<...>>
的{{1}}是second
所包含内容的一种“高级”信息,因此在许多地方,我想投射/转换此对象类似于std::pair
的类first
到其std::pair
的类型。
解决方法
当编译器看到d == B{2}
时,它首先会找到creates a list of operator==
overloads,然后对其执行重载解析。
如链接所述,过载列表包含:
- 第一个操作数的成员
operator==
(如果有)。 - 通过不合格查找找到的非成员
operators==
。 - 内置
operator==
,如果您的操作数可以转换为内置类型。
没有提到检查第一个操作数的转换运算符,因此找不到您的operator==
。
解决方案是使operator==
成为非成员(可能将其定义为friend
)。这有效:
friend bool operator==(const B &a,const B &b) {return a.x == b.x;}
从C ++ 20开始,比较运算符的规则放宽了:编译器还将在第二个操作数中查找成员operator==
,并愉快地使用参数调用非成员operator==
顺序错误。
因此a == b
和b == a
现在相当于一个学位,除了:
- 以这种新方式调用的
operator==
必须返回bool
。 - 如果有选择,相对于调用rhs的成员
operator==
,编译器将更喜欢使用旧的调用operator==
的方法,这又比调用非成员operator==
更好。参数顺序错误。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。