Странная ошибка `std::variant::operator==` с clang + libc++ и определенным количеством вариантовC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Странная ошибка `std::variant::operator==` с clang + libc++ и определенным количеством вариантов

Сообщение Anonymous »

Это очень странно и, скорее всего, это ошибка clang, но сначала я хочу убедиться в этом, чтобы не рассылать разработчикам спам с недопустимыми проблемами.
Я сократил свой вариант использования до простого примера, где clang выдает ошибку, которой, я почти уверен, не должно быть. Как ни странно, если я поиграю с количеством альтернатив, проблема чудесным образом исчезнет. Другие компиляторы не выдают никаких ошибок, а также не конфликтуют с libstdc++ (доступен на godbolt.com).

Код: Выделить всё

// Set 1/2/3 to pick different use cases
#define USE_CASE 1

#include 
#include 

struct Array;

struct A1 { auto operator(const A1 &) const = default; };
struct A2 { auto operator(const A2 &) const = default; };
struct A3 { auto operator(const A3 &) const = default; };
struct A4 { auto operator(const A4 &) const = default; };
struct A5 { auto operator(const A5 &) const = default; };
struct A6 { auto operator(const A6 &) const = default; };
struct A7 { auto operator(const A7 &) const = default; };
struct A8 { auto operator(const A8 &) const = default; };
struct A9 { auto operator(const A9 &) const = default; };

using Var1 = std::variant<
A1
, A2
, A3
, A4
, A5
, A6
, A9
, Array
>;

struct Array : public std::vector
{
using vector::vector;
};

#if USE_CASE == 1

// This fails
using Var2 =
std::variant<
A1
, A2
, A3
, A4
, A5
, A6
, A7
, Array
>;

#elif USE_CASE == 2

// This does not fail
using Var2 =
std::variant<
A1
, A2
, A3
, A4
, A5
, A6
//, A7
, Array
>;

#elif USE_CASE == 3

// This does not fail
using Var2 =
std::variant<
A1
, A2
, A3
, A4
, A5
, A6
, A7
, A8
, Array
>;

#endif

static_assert(std::equality_comparable);

int main()
{
constexpr bool foo = Var2{} == Var2{};
return 0;
}
Только если USE_CASE равен 1. У clang есть проблемы. В двух других случаях, когда какая-то альтернатива удаляется или добавляется, все в порядке. Как ни странно, std::equality_comparable всегда выдает true, намекая на обман. Похоже, 8 — это какое-то магическое число (оптимизация в libc++?).
Обновление:
Благодаря TC тестовый пример был значительно упрощен (доступен на godbolt.com):

Код: Выделить всё

#include 
#include 

struct Array;

struct A1 { auto operator(const A1 &) const = default; };
struct A2 { auto operator(const A2 &) const = default; };

using Var1 =
std::variant<
A1
, Array
>;

struct Array : public std::vector
{
using vector::vector;
};

// This fails
using Var2 =
std::variant<
A2
, Array
>;

static_assert(std::equality_comparable);

int main()
{
constexpr bool foo = Var2{} == Var2{};
return 0;
}
И благодаря отзывам от 0___________ об ошибке было сообщено.

Подробнее здесь: https://stackoverflow.com/questions/798 ... c-number-o
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»