TGViewer
this->notes. this->notes. @thisnotes · 4.52K subscribers
Post #178 903
#cpp

Уже больше полугода откладывал этот пост, потому что его написание требовало не просто время на сесть и выродить из себя k предложений текста с примерами кода, а пересмотреть несколько нетривиальных докладов.
Но я справился, так что верю, что и вы.

Немного из метапрограммирования 1/2.

1. type_identity (С++20).

Это очень простой хелпер для реализации множества других type trait’ов:

template <typename T>
struct type_identity { using type = T; };


Например можно использовать вот так:

template <typename T>
struct remove_reference : type_indentity<T> {};
template <>
struct remove_reference<T&> : type_indentity<T> {};
template <>
struct remove_reference<T&&> : type_indentity<T> {};


Конечно же, можно сокращать гораздо более сложные конструкции.

2. void_t (C++17).

void_t это алиас на void:

template <typename…>
using void_t = void;


Это очень маленький кусочек кода, который позволяет творить на самомо деле очень крутые вещи. Обычно он используется для валидации выражений на компиляции и включения SFINAE.

Давайте посмотрим, какие с void_t есть проблемы.

struct One { using x = int; };
struct Two { using y = int; };

template <typename T, std::void_t<typename T::x>* = nullptr>
void f() {}
template <typename T, std::void_t<typename T::y>* = nullptr>
void f() {}

int main() {
f<One>();
f<Two>();
}


При попытке скомпилировать данный код, мы получим redefinition of function f. Но мы же знаем, что всё должно работать! Давайте попробуем заменить void_t на что-то другое (покажем только изменившийся код):

template <typename ...Args> using MyType = void;
template <typename T, MyType<typename T::x>* = nullptr>
void f() {}
template <typename T, MyType<typename T::y>* = nullptr>
void f() {}


Такой код по факту ничем не отличается и не работает (однако ведёт нас к успеху). Давайте попробуем исправить проблему и увидеть, что же было не так. Т.к. void является довольно специфическим типом, давайте заменим его на что-то более обычное:

struct MyTypeT {};
template <typename ...Args> using MyType = MyTypeT;


Сейчас мы увидим те же ошибки компиляции, что и ранее. Но если мы сделаем ещё одно небольшое изменение:

struct MyTypeT {};
template <typename ...Args> struct MyType : MyTypeT {};


всё заработает.

Или если мы реализуем void_t вот так:

template <typename T, typename…>
struct void_t_impl : type_identity<T> {}

template <typename… Args>
using void_t = typename void_t_impl<void, Args…>::type;


и заюзаем такой в первом примере, всё заработает!

Давайте поймём, почему не работает. template type alias’ы с C++11 являются упрощённой конструкцией в языке, специально чтобы все штуки вроде type_trait_t/type_trait_v работали как можно быстрее. И по факту они просто заменяются на то, что алиасят. В C++14 решили сказать, что все dependent штуки из шаблонов templated type alias’ов должны где-то запоминаться (хотя вообще-то никакого запоминания инстанцированных версий у них нет). Получилось противоречие в стандарте, когда вообще-то должно запоминаться и разруливаться в смысле SFINAE, но получается, что просто заменяется на void и ничего не работает. Тогда как со структурой такого не происходит.

Пример отсюда. Более подробное пояснение тут.
  • 👍 9
More from @thisnotes
  1. Sep 17, 2026#common Сидите вы себе спокойно, разрабатываете поиск каких-нибудь объектов. Может это тов…
  2. Sep 9, 2026#cpp #books Да, книга 2001ого года. Мы ровесники. И да, в ней в основном обсуждаются какие…
  3. Sep 2, 2026#perf Попробовал собрать в кучку (кажется, немного сумбурно всё же) мысли по двум моментам…
  4. Aug 31, 2026Давайте новый тег заведём: #perf Во-первых, надо понять, что я вообще понимаю под перфом,…
  5. Aug 27, 2026#common Мы часто делаем системы, которые обладают какими-то ограничениями. Ограничения наш…
  6. Aug 24, 2026#list 0. [talk] Achieving Peak Performance for Matrix Multiplication in C++. Aliaksei Sala…
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 →