Эта черта проходит, потому что существует метод, который можно найти с помощью разрешения перегрузки, и он не удален.
На самом деле его вызов не удался, потому что реализация метода содержит код, недопустимый для этих двухтипы.
В C ++ вы не можете проверить, приведет ли создание экземпляра метода к ошибке компиляции, вы можете проверить только эквивалент эквивалентного разрешения перегрузки, найдя решение.
Язык C ++ и стандартИзначально библиотека в значительной степени опиралась на «хорошо, тело метода компилируется только в шаблоне, если вызывается, поэтому, если тело неверно, программисту будет сказано».Более современный C ++ (как внутри, так и вне стандартной библиотеки) использует SFINAE и другие методы, чтобы сделать метод «не участвующим в разрешении перегрузки», когда его тело не будет компилироваться.
Конструктор обратного итератора из других обратных итераторовявляется старым стилем и не был обновлен до качества "не участвовать в разрешении перегрузки".
С n4713 , 27.5.1.3.1 [reverse.iter.cons] / 3:
template<class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
Эффекты: Инициализирует ток с помощью u.current.
Обратите внимание на отсутствие упоминания о «не участвует в разрешении перегрузки» или подобных словах.
Единственный способ получить желаемую черту - это
Изменить (ну, исправить) стандарт C ++
Особый случай это
Я оставлю 1. в качестве упражнения.Для 2. вы знаете, что обратные итераторы являются шаблонами перед прямыми итераторами.
template<class...Ts>
struct my_trait:std::is_assignable<Ts...> {};
template<class T0, class T1>
struct my_trait<std::reverse_iterator<T0>, std::reverse_iterator<T1>>:
my_trait<T0, T1>
{};
и теперь my_trait
равен is_assignable
, за исключением обратных итераторов, где вместо этого проверяется назначаемость содержащихся итераторов.
(Как забавно, обратный обратный итератор будет работать с этой чертой).
Мне когда-то приходилось делать что-то очень похожее с std::vector<T>::operator<
, который также слепо вызывал T<T
и не делалSFINAE отключите его, если это недопустимо.
Может также случиться, что реализация стандартной библиотеки C ++ может создать конструктор, который не будет компилироваться, не будет участвовать в разрешении перегрузки.Это изменение может нарушить в противном случае правильно сформированные программы, но только из-за таких нелепых вещей, как ваше статическое утверждение (которое может измениться) или из-за логического эквивалентности.