Я думаю, что это ошибка Boost.
type requirements здесь:
- CopyConstructible или MoveConstructible.
- Деструктор поддерживает гарантию отсутствия безопасности.
- Завершить создание экземпляра шаблона варианта. (См
boost::recursive_wrapper<T>
для типа обертки, который принимает неполные типы, чтобы позволить рекурсивные типы вариантные.)
, а также:
- EqualityComparable:
variant
сама по себе EqualityComparable тогда и только тогда, когда каждый из его ограниченных типов отвечает требованиям концепции.
ссылочный тип копия конструктивны, не перекидной разрушаемость, полное и равенство сопоставимыми. Таким образом, у нас все хорошо. Вопрос заключается в том, что посетитель, используемый в реализации является:
template <typename T>
bool operator()(const T& rhs_content) const
{
// Since the precondition ensures lhs and rhs types are same, get T...
known_get<const T> getter;
const T& lhs_content = lhs_.apply_visitor(getter);
// ...and compare lhs and rhs contents:
return Comp()(lhs_content, rhs_content);
}
То есть, мы используем const T
как известный добытчик.Это хорошо для не-ссылочных типов, но неверно для ссылочных типов, так как known_get
утверждает, если он получает неправильный тип:
T& operator()(T& operand) const BOOST_NOEXCEPT
{
return operand;
}
template <typename U>
T& operator()(U&) const
{
// logical error to be here: see precondition above
BOOST_ASSERT(false);
return ::boost::detail::variant::forced_return<T&>();
}
С int&
, эти перегрузки стали:
const int& operator()(const int&) const;
const int& operator()(int&) const; [ U = int ]
Вторая перегрузка предпочтительнее, поскольку тип, на который он ссылается, будет менее const-квалифицированным, чем не-шаблонная перегрузка. Вот почему вы получаете утверждение, и это поведение явно неверно. Мы должны иметь возможность сравнивать ссылки!
Чем проще решение было бы отбросить const
с от comparer
и просто использовать:
template <typename T>
bool operator()(T& rhs_content) const
{
known_get<T> getter;
T& lhs_content = lhs_.apply_visitor(getter);
return Comp()(lhs_content, rhs_content);
}
Это будет работать для ссылочных типов, а также const
типов.
Я ничего не вижу о вариантах ссылок в документации по ускорению. так UB? –
Я так не думаю. Хотя это правда, что документы и esp. в учебнике ничего не говорится о хранении ссылок, кажется, нет препятствий для использования их вариантов. – Engineerist