Это скорее концептуальный вопрос. Я пытаюсь найти самый простой способ преобразования шаблона с двумя аргументами (аргументы типа) в шаблон с одним аргументом. I.e., связывая один из типов.
Это будет мета-программный эквивалент bind
в boost/std. Мой пример включает возможный прецедент, который передает std::is_same
в качестве аргумента шаблона шаблону, который принимает аргумент шаблона шаблона с одним аргументом (std::is_same
является шаблоном с двумя аргументами), то есть до TypeList::FindIf
. TypeList
здесь не полностью реализована, и не FindIf
, но вы получаете идею. Он принимает "унарный предикат" и возвращает тип, для которого этот предикат является истинным, или void
, если не такой тип.
У меня есть 2 рабочих варианта, но первый не является однострочным, а второй использует довольно подробное приспособление BindFirst
, которое не будет работать для аргументов шаблона, отличного от типа. Есть ли простой способ написать такой однострочный шрифт? Я считаю, что процедура, которую я ищу, называется currying
.
#include <iostream>
template<template<typename, typename> class Function, typename FirstArg>
struct BindFirst
{
template<typename SecondArg>
using Result = Function<FirstArg, SecondArg>;
};
//template<typename Type> using IsInt = BindFirst<_EqualTypes, int>::Result<Type>;
template<typename Type> using IsInt = std::is_same<int, Type>;
struct TypeList
{
template<template<typename> class Predicate>
struct FindIf
{
// this needs to be implemented, return void for now
typedef void Result;
};
};
int main()
{
static_assert(IsInt<int>::value, "");
static_assert(!IsInt<float>::value, "");
// variant #1: using the predefined parameterized type alias as predicate
typedef TypeList::FindIf<IsInt>::Result Result1;
// variant #2: one-liner, using BindFirst and std::is_same directly
typedef TypeList::FindIf< BindFirst<std::is_same, int>::Result>::Result Result2;
// variant #3: one-liner, using currying?
//typedef TypeList::FindIf<std::is_same<int, _>>::Result Result2;
return 0;
}
Нажмите здесь для кода в онлайн-компиляторе GodBolt.