Consider:
#include <variant>
struct A {
A() = default;
A(A&&) = delete;
};
struct B {
B() = delete;
B(A&&) {};
};
int main() {
std::variant<A, B> v{};
v = A{};
}
MSVC accepted it, while GCC and Clang rejected it with the same error message:
opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/12.0.0/../../../../include/c++/12.0.0/variant:1465:3: error: call to deleted member function 'operator='
operator=(variant(std::forward<_Tp>(__rhs)));
^~~~~~~~~
<source>:15:5: note: in instantiation of function template specialization 'std::variant<A, B>::operator=<A>' requested here
v = A{};
^
Which compiler should I trust?
EDIT
Initially, there was no language-lawyer
tag, which was why I used cppreference for the analysis. However, looking into the latest draft (relevant section), I don't see anything that would make it invalid.
I believe MSVC is incorrect. According to the documentation:
- Converting assignment.
Determines the alternative type
T_j
that would be selected by overload resolution for the expressionF(std::forward<T>(t))
if there was an overload of imaginary functionF(T_i)
for everyT_i
fromTypes...
in scope at the same time, except that:
- An overload
F(T_i)
is only considered if the declarationT_i x[] = { std::forward<T>(t) };
is valid for some invented variablex
;
With some imaginary function having forwarding reference parameter and calling it with A{}
argument, A x[] = { std::forward<T>(t) };
is not valid while B x[] = { std::forward<T>(t) };
is. Consequently , T_j
should be resolved as B
. Live demo: https://godbolt.org/z/fM67e7oGj.
Then:
- If
*this
already holds aT_j
...
This does not apply, since v
does not hold a B
.
Next:
- Otherwise, if
std::is_nothrow_constructible_v<T_j, T> || !std::is_nothrow_move_constructible_v<T_j>
istrue
...
This also does not apply, since this expression is false
; live demo: https://godbolt.org/z/x674rnbcj (and, MSVC agrees on that: https://godbolt.org/z/5Techn8jG).
Finally:
- Otherwise, equivalent to
this->operator=(variant(std::forward<T>(t)))
.
However, this call does not compile with MSVC: https://godbolt.org/z/cWr4f6EhK.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With