Почему std :: option не может сравниться с одним из его альтернативных типов? - PullRequest
8 голосов
/ 20 марта 2019

Например, было бы очень полезно сравнить std::variant<T1, T2> с T1 или T2.Пока что мы можем сравнивать только с одним и тем же типом варианта.

Ответы [ 3 ]

8 голосов
/ 20 марта 2019

Вариант может иметь несколько дубликатов одного типа. Например. std::variant<int, int>.

Данный экземпляр std::variant сравнивается равным с другим, если и только если они содержат одну и ту же альтернативную альтернативу, а значения указанных альтернатив сравниваются равными.

Таким образом, std::variant<int, int> с index() 0 сравнивается не равным std::variant<int, int> с index() 1, несмотря на то, что активные альтернативные варианты имеют тот же тип и то же значение.

Из-за этого стандартное «сравнение с T» не было реализовано стандартом. Однако вы можете самостоятельно спроектировать перегрузку операторов сравнения, используя другие вспомогательные утилиты в заголовке <variant> (например, std::holds_alternative и std::get<T>).

2 голосов
/ 21 марта 2019

Я не могу ответить на часть почему вопроса, но, поскольку вы думаете, было бы полезно иметь возможность сравнить std::variant<T1, T2> с T1 или T2, возможно, это может Справка:

template<typename T, class... Types>
inline bool operator==(const T& t, const std::variant<Types...>& v) {
    const T* c = std::get_if<T>(&v);
    if(c)
        return *c == t;
    else
        return false;
}

template<typename T, class... Types>
inline bool operator==(const std::variant<Types...>& v, const T& t) {
    return t == v;
}
1 голос
/ 20 марта 2019

Это произвольное решение комитета по стандартам.

Хорошо, не вполне произвольно.Дело в том, что у вас есть шкала * строгости сравнения с такими точками, как:

  • Наиболее строгий: только варианты могут совпадать, и они должны соответствовать обоимв последовательности альтернатив (т. е. типе), фактической альтернативе (на самом деле это индекс, поскольку вы можете иметь несколько альтернатив идентичного типа) и в значении.
  • Менее строгий: Равенство обоихвариант варианта, как тип и значение, но не последовательности альтернатив или индекса в этой последовательности (поэтому одно и то же значение в двух различных альтернативах одного типа будет равно).
  • Наиболее расслабленный: Равенство значения в активной альтернативе с неявным преобразованием одного из элементов, если это уместно.

Это все допустимые варианты.Комитет C ++ принял решение на основе всевозможных внешних критериев.Попробуйте поискать предложение std::variant, так как, возможно, в нем говорится, каковы эти критерии.

(*) - решетка на самом деле.

...