TGViewer
C++: Хроники Дурки🚑 C++: Хроники Дурки🚑 @cpp_durka · 916 subscribers
Post #68 1.57K
Вместо дурки я сегодня продолжаю пересматривать доклад великолепного Константина Владимирова.

Жду не дождусь, когда он появится в открытом доступе, чтобы поскидывать интересные таймкоды. Это будет легко, просто скриптом каждые две минуты написать....

Вместо дурки хочу поделиться интересной конструкцией, о которой до этого не знал, но почерпнул из того доклада.


Пусть у нас есть класс:


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>
>);
}
Telegram C++ and other lectures Всем привет. Кто идёт на C++ Russia из моих уважаемых подписчиков, обратите пожалуйста внимание на изменения в программе, внесённые в последний момент. https://cppconf.ru/schedule/table/#day-2 Теперь мой доклад открывает конференцию в субботу утром, а Антон…
  • 😁 29
  • 👌 4
  • ❤ 3
  • 🤯 2
More from @cpp_durka
  1. Sep 8, 2026Мошенники заставили пенсионерку из Москвы переписать квартиру на Rust
  2. Aug 31, 2026Всяко разное болезненное есть в С++, из всего болезненного одно из самых болезненных - это…
  3. Aug 24, 2026Если кто не знаком с библиотекой nlohmann/json - она прекрасна. Мои мысли о том, как должн…
  4. Aug 21, 2026#толькосвоимемы Код взят тут. if (dim == 0) idx_dim = i0; else if (dim == 1) idx_dim = i1;…
  5. Aug 17, 2026Ладно, искать баги в компиляторах весело, но недостаточно. Давайте поиграемся в чуть более…
  6. Aug 10, 2026Ладно, разумеется прошлый пост был набросом. Никогда не обновляйте компиляторы без очень с…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →