Жду не дождусь, когда он появится в открытом доступе, чтобы поскидывать интересные таймкоды. Это будет легко, просто скриптом каждые две минуты написать....
Вместо дурки хочу поделиться интересной конструкцией, о которой до этого не знал, но почерпнул из того доклада.
Пусть у нас есть класс:
template<typename T>
struct S {
S(T) {
std::cout << "S(T)" << std::endl;
}
template<typename Iter>
S(Iter beg, Iter end) {
(beg); (end);
std::cout << "S(Iter beg, Iter end)" << std::endl;
}
};
Если мы напишем что-то такое:
int a = 3;
auto s1 = S(a);
static_assert(std::same_as<decltype(s1),
S<int>>
);
То оно нормально скомпилируется.
А вот если мы попробуем как-то тригернуть второй конструктор:
std::vector<double> v;
auto s2 = S(v.begin(), v.end());
То ожидаемо упадем с ошибкой, смысл которой сводится к тому, что компилятор не знает, какой именно тип выводить.
error: no viable constructor or deduction guide for deduction of template arguments of 'S'
Что довольно логично.
Но оказывается, есть возможность указать "хинт" для того, какой тип должен выводить конструктор класса!
template<typename Iter>
S(Iter, Iter)
-> S<typename std::iterator_traits<Iter>::value_type>;
И тогда вот это компилируется:
https://godbolt.org/z/MaPo7PsP4
std::vector<double> v;
auto s2 = S(v.begin(), v.end());
static_assert(std::same_as<decltype(s2),
S<double>>
);
У Константина дальше в докладе было всякое, какие у этого есть побочные эффекты. Посмотрите доклад потом сами.
Много примеров есть прямо вот тут:
https://eel.is/c%2B%2Bdraft/over.match.class.deduct
А меня просто понесло. Мне так нравятся типы, которые меняются при каждом копировании, кто бы знал (и да, весь пост написан только ради этой ржаки):
https://godbolt.org/z/4EMnjWsza
#include <concepts>
struct Charmander {};
struct Charmeleon {};
struct Charizard {};
template<typename Form>
struct Pokemon {
Pokemon(Form) {}
template<typename OtherForm>
Pokemon(const Pokemon<OtherForm>&) {}
};
Pokemon(const Pokemon<Charmander>&)
-> Pokemon<Charmeleon>;
Pokemon(const Pokemon<Charmeleon>&)
-> Pokemon<Charizard>;
Pokemon(const Pokemon<Charizard>&)
-> Pokemon<Charmander>;
int main() {
Pokemon p1 = Charmander{};
Pokemon p2 = p1;
Pokemon p3 = p2;
Pokemon p4 = p3;
static_assert(std::same_as<
decltype(p1),
Pokemon<Charmander>
>);
static_assert(std::same_as<
decltype(p2),
Pokemon<Charmeleon>
>);
static_assert(std::same_as<
decltype(p3),
Pokemon<Charizard>
>);
static_assert(std::same_as<
decltype(p4),
Pokemon<Charmander>
>);
}