std::type_fn и std::value_fn для работы с std:type_identity в value-based контексте

Олег Фатхиев
Олег Фатхиев

Чтобы следовать тенденции комитита относительно метапрограммирования в сторону value-based подхода, предлагается как можно раньше добавить следующие сущности:

template <template <class...> class F>
struct type_fn {
    template <class... Ts>
    constexpr auto operator()(type_identity<Ts>...) {
        return type_identity<typename F<Ts...>::type>{};
    }
};
template <template <class...> class F>
constexpr type_fn<F> type_fn_v;

template <template <class...> class F>
struct value_fn {
    template <class... Ts>
    constexpr auto operator()(type_identity<Ts>...) {
        return F<Ts...>::value;
    }
};
template <template <class...> class F>
constexpr value_fn<F> value_fn_v;

Это поможет использовать метафункции в value-based контексте:

constexpr std::type_identity<int> t1;
constexpr std::type_identity<double> t2;

constexpr auto common_type_v = std::type_fn_v<std::common_type>;
constexpr auto is_same_v = std::value_fn_v<std::is_same>

constexpr auto t3 = common_type_v(t1, t2);
static_assert(is_same_v(t3, std::type_identity<double>{}));
0
рейтинг
8 комментариев
yndx-antoshkka

Сейчас всё метапрограммирование поставлено на паузу до тех пор, пока не выйдет Reflections TS. Когда он выйдет, его ещё раз поменяют в сторону обычных переменных:

constexpr auto t1 = reflexpr(int);
constexpr auto t2 = reflexpr(double);

constexpr auto t3 = ????(t1, t2);
static_assert(t3 == reflexpr(double));

std::type_identity там просто не будет использоваться.

Но вот идея сделать так, чтобы type_traits работали с reflexpr - весьма годная! Попробуйте подумать, как это сделать, и перепроверить, нет ли уже готовой базы для этого в Reflections TS

yndx-antoshkka
Andrey Davydov

yndx-antoshkka, говоря "type_traits работали с reflexpr" Вы имеете в виду, возможность с constexpr-based рефлексией вместо TriviallyCopyable<X> писать reflexpr(X).is_trivially_copyable()? А существует ли вообще хоть какой-то набросок интерфейса constexpr-based рефлексии (всех-этих классов meta::type, meta::expression и т.д.)?

Andrey Davydov
yndx-antoshkka

Andrey Davydov, да, что-то наподобие reflexpr(X).is_trivially_copyable()

Набросок интерфейса есть тут http://wg21.link/P0953

yndx-antoshkka
Andrey Davydov

yndx-antoshkka, в том proposal-е, на который Вы сослались, есть даже секция type_traits. И в альтернативном предложении http://wg21.link/p1240 (который мне нравится даже больше) также есть соответствующий раздел: "Transcribing the standard library's [meta] section".

 

Andrey Davydov
yndx-antoshkka

Andrey Davydov, о, я эту секцию упустил из виду. Тогда что остаётся от идеи? common_type_v просто добавить нельзя, будет конфликс с имеющимися type_traits.

yndx-antoshkka
Andrey Davydov

yndx-antoshkka, наверное, предложение Олега все равно имеет смысл для пользовательских метафункций (или таких трейтов, как common_type, которые могут быть специализированы пользователем). Только реализация в мире с reflection будет совсем другой, попробовал набросать в терминах http://wg21.link/p1240:

auto value_fn_v(meta::info F) {
    return [F] (span<meta::info> types) {
        return template(F)<(<types>)...>::value;
    };
}

auto is_same_v = value_fn_v(reflexpr(std::is_same));
static_assert(!is_same_v({ reflexpr(int), reflexpr(float) }));
Andrey Davydov
yndx-antoshkka

В таком виде выглядит очень полезным. Надо попробовать накидать рабочий прототип и можно закидывать бумагу в SG7 Reflections and Metaprogramming.

yndx-antoshkka
Олег Фатхиев

yndx-antoshkka, ок, разузнаю поподробнее и напишу вам.

Олег Фатхиев
Обновлено 
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения