Как работает std::is_convertible::value?
Копался в файлах chromium-a и наткнулся вот на этот
Вот кусочек, в котором происходит какая-то магия.
template <
typename U,
std::enable_if_t<std::is_convertible<U (*)[], T (*)[]>::value>* = nullptr>
constexpr CheckedContiguousIterator(const CheckedContiguousIterator<U>& other)
: start_(other.start_), current_(other.current_), end_(other.end_) {
// We explicitly don't delegate to the 3-argument constructor here. Its
// CHECKs would be redundant, since we expect |other| to maintain its own
// invariant. However, DCHECKs never hurt anybody. Presumably.
DCHECK_LE(other.start_, other.current_);
DCHECK_LE(other.current_, other.end_);
}
Объясните, пожалуйста, что происходит вот в этой строке:
template <typename U, std::enable_if_t<std::is_convertible<U (*)[], T (*)[]>::value>* = nullptr>
- почему " = nullptr"?
- что такое "U (*)[]" и как оно работает?
Ответы (1 шт):
почему " = nullptr"?
Нипочему. Ну то есть могло бы быть написано по-другому, не меняя сути.
'std::enable_if_t' используется как шаблонный параметр для SFINAE, если подстановка первого параметра для неудачна, 'std::enable_if_t' не скомпилируется и функция выбросится. В случае удачной подстановки, enable_if_t является typedef для своего второго шаблонного параметра, который по умолчанию void. Чтобы в функции не было лишних шаблонных параметров, параметр, образованный enable_if_t делают по умолчанию. Вариантов много:
enable_if_t<..., void>* = nullptr- более длинная запись того, что в исходном примереenable_if_t<..., int> = 0- вариант с шаблонным параметром intclass = enable_if_t<...>- вариант с шаблонным параметром типом
что такое "U (*)[]" и как оно работает?
Указатель на массив. По ссылке в комментарии объяснение.