Currying para modelos em metaprogramação em C ++
Esta é mais uma questão conceitual. Estou tentando encontrar a maneira mais fácil de converter um modelo de dois argumentos (os argumentos sendo tipos) em um modelo de um argumento. Ou seja, vinculando um dos tipos.
Este seria o equivalente de meta-programação debind
em boost / std. Meu exemplo inclui um possível caso de uso, ou seja, passarstd::is_same
como argumento de modelo para um modelo que usa um argumento de modelo de um argumento (std::is_same
sendo um modelo de dois argumentos), ou seja, paraTypeList::FindIf
. oTypeList
não está totalmente implementado aqui, nemFindIf
, mas você entendeu a ideia. Ele pega um "predicado unário" e retorna o tipo para o qual esse predicado é verdadeiro, ouvoid
se não for esse tipo.
Eu tenho 2 variantes de trabalho, mas o primeiro não é um one-liner e o segundo usa um bastante detalhadoBindFirst
engenhoca, que não funcionaria para argumentos de modelo não-tipo. Existe uma maneira simples de escrever uma única linha? Eu acredito que o procedimento que estou procurando é chamadocurrying
.
#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;
}
Cliqueaqui para código no compilador online GodBolt.