'std::variant behaves differently in MSVC and gcc
Update: This is a C++ standard defect, which is fixed in C++20 (P0608R3). Also, VS 2019 16.10 has fixed this bug with /std:c++20.
MSVC 19.28 rejects the following code but gcc 10.2 accepts it and outputs true false
#include <iostream>
#include <variant>
int main()
{
std::variant<long long, double> v{ 0 };
std::cout << std::boolalpha << std::holds_alternative<long long>(v) << ' ' << std::holds_alternative<double>(v) << std::endl;
}
According to cppreference:
- Converting constructor. Constructs a variant holding the alternative type
T_jthat 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_ifromTypes...in scope at the same time, except that: An overloadF(T_i)is only considered if the declarationT_i x[] = { std::forward<T>(t) };is valid for some invented variablex; Direct-initializes the contained value as if by direct non-list-initialization fromstd::forward<T>(t).
And the question is converted to which function of F(long long) and F(double) is selected agianst argument 1 by overload resolution.
Converting int to long long is an integral conversion (supposing sizeof(long long) is bigger than sizeof(int)) and converting int to double is an floating-integral conversion, neither ranks higher that the other. So the call is ambiguous and the program is ill-formed.
MSVC does rejected the code as I expected but to my surprise, gcc accepts it. Besides, there is also a similar example on cppreference:
std::variant<std::string> v("abc"); // OK
std::variant<std::string, std::string> w("abc"); // ill-formed
std::variant<std::string, const char*> x("abc"); // OK, chooses const char*
std::variant<std::string, bool> y("abc"); // OK, chooses string; bool is not a candidate
/* THIS ONE -> */ std::variant<float, long, double> z = 0; // OK, holds long
// float and double are not candidates
So my question is: is gcc or MSVC non-conformance, or my understanding is wrong?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
