Рассмотрим следующие статические утверждения:
static_assert(std::is_convertible_v<int const&, int const>);
static_assert(std::is_convertible_v<int const, int>);
static_assert(std::is_convertible_v<int, int &&>);
static_assert(std::is_convertible_v<int const&, int &&>);
Вышеупомянутые три утверждения проходят, но последнее утверждение не выполняется.
Это означает, что конвертируемость типов в C ++ в целом не транзитивна, чтоЯ думаю, что это очень нелогично.
Я искал стандарт и веб-сайт cppreference, чтобы найти какие-либо доказательства того, что это предполагаемое поведение, но я пока не добился успеха.
Интересно, для lvalue-ссылки, все хорошо, потому что std::is_convertible_v<int, int&>
ложно.Я также ожидал бы, что для rvalue-ссылок.
Я предполагаю, что это как-то связано с тем, как определяется is_convertible
.В определении аргумент To
появляется как тип возврата мнимой функции.Насколько я понимаю, свежее значение любого типа является временным и поэтому может быть преобразовано в rvalue-ссылку.Поэтому std::is_convertible_v<T, T&&>
справедливо для любого типа T
.
Поэтому, в частности, я задаю следующие вопросы:
- Действительно ли
is_convertible
захватывает интуицию конвертируемости? - Если нет, что еще он захватывает?Или по-другому: не подходит ли моя интуиция конвертируемости?
- Если мы понимаем
is_convertible
как бинарное отношение, не должно ли это быть предзаказом, то есть транзитивным?Почему бы и нет?
Интуитивно, imho, конвертируемость должна означать: всякий раз, когда требуется тип To
, вы также можете использовать тип From
.И это подразумевает транзитивность.
В частности, T
не должен быть конвертируемым в T&&
, потому что вы не можете использовать T
, где требуется T&&
(вы не можете перейти от T
например, но вы можете перейти от T&&
).
Я что-то здесь серьезно ошибаюсь?