admin管理员组文章数量:1430735
Snip:
#include <optional>
template <typename>
class MyOpt;
template <typename T>
MyOpt(T) -> MyOpt<T>;
template <typename T>
class MyOpt : private std::optional<T>
{
public:
using std::optional<T>::optional;
using std::optional<T>::operator=;
};
int main() {
MyOpt o{42};
o=52;
return 0;
}
This code fails to compile with some ambiguity error:
error: ambiguous overload for 'operator=' (operand types are 'MyOpt' and 'int')
note: candidate: 'constexpr MyOpt& MyOpt::operator=(const MyOpt&)'
note: candidate: 'constexpr MyOpt& MyOpt::operator=(MyOpt&&)'
see
What is the reason for this failure and can this be "fixed"(c++20 at disposal), such that in the derived class I do not have to reimplement the assignment operator?
Snip:
#include <optional>
template <typename>
class MyOpt;
template <typename T>
MyOpt(T) -> MyOpt<T>;
template <typename T>
class MyOpt : private std::optional<T>
{
public:
using std::optional<T>::optional;
using std::optional<T>::operator=;
};
int main() {
MyOpt o{42};
o=52;
return 0;
}
This code fails to compile with some ambiguity error:
error: ambiguous overload for 'operator=' (operand types are 'MyOpt' and 'int')
note: candidate: 'constexpr MyOpt& MyOpt::operator=(const MyOpt&)'
note: candidate: 'constexpr MyOpt& MyOpt::operator=(MyOpt&&)'
see https://godbolt./z/jvMMGh9Gn
What is the reason for this failure and can this be "fixed"(c++20 at disposal), such that in the derived class I do not have to reimplement the assignment operator?
Share Improve this question edited Nov 19, 2024 at 15:53 cigien 60.6k11 gold badges82 silver badges121 bronze badges asked Nov 19, 2024 at 12:45 JuergenJuergen 3,7417 gold badges37 silver badges71 bronze badges 5 |1 Answer
Reset to default 2The problem is that you are trying to invoke the inherited assignment operator that cannot be called for scalar types. This is the overload (4) in cppreference. Note the following quote about this "forwarding" assignment operator:
The function does not participate in overload resolution unless ... and at least one of the following is true:
T
is not a scalar type;std::decay_t<U>
is notT
.
In your case, T
is int
, which is a scalar type, and std::decay_t<U>
is int
as well, and therefore it is also T
.
A simple demo of this cause is using a non-scalar type; then, everything works fine: https://godbolt./z/cbasffaEM.
A demo of the same problem with custom simplified optional
: https://godbolt./z/KnojW8z91. If you comment out the requires
clause, then, the problem disappears.
A relevant part of the libstdc++ implementation of std::optional::operator=
is here.
If you wonder why there is that condition about scalar types, I recommend reading this question: Why does std::optional::operator=(U&&) require U to be a non-scalar type?
As for that ambiguity, if I understand things correctly, the assignment now involves creating a temporary and calling move assignment operator. The problem is that there are two move assignment operators that can be used (one implicitly defined for MyOpt
and the other one inherited from std::optional
). And the compiler cannot decide which one to use. Clang provides a more understandable error message about this issue: https://godbolt./z/8Yb1qPzT1.
With std::optional
itself, there is no such ambiguity, since only its move assignment operator can be called.
本文标签: inheritanceInherit assignment operator failure cStack Overflow
版权声明:本文标题:inheritance - Inherit assignment operator failure c++ - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745561434a2663494.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
operator=
you pull in with theusing
statement? – Mark Ransom Commented Nov 19, 2024 at 15:57using .. operator=
line. But I'm not sure what effect(s) that may have further down the road. – Adrian Mole Commented Nov 19, 2024 at 19:44