cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
88 stars 0 forks source link

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

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +0, -0 Автор идеи: Олег Фатхиев

Предлагается добавить std::type_fn и std::value_fn для оборачивания метафункций в constexpr функторы, которые в качестве аргументов используют std::type_identity

Чтобы следовать тенденции комитита относительно метапрограммирования в сторону 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>{}));
apolukhin commented 3 years ago

yndx-antoshkka, 26 февраля 2019, 12:13 Сейчас всё метапрограммирование поставлено на паузу до тех пор, пока не выйдет 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

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

yndx-antoshkka, 27 февраля 2019, 16:57 Andrey Davydov, да, что-то наподобие reflexpr(X).is_trivially_copyable()

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

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

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

Andrey Davydov, 27 февраля 2019, 23:43 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) }));

yndx-antoshkka, 28 февраля 2019, 14:18 В таком виде выглядит очень полезным. Надо попробовать накидать рабочий прототип и можно закидывать бумагу в SG7 Reflections and Metaprogramming.

Олег Фатхиев, 28 февраля 2019, 15:58 yndx-antoshkka, ок, разузнаю поподробнее и напишу вам.