I really wanted to solve this myself, but spending hours looking at the same code again and again is not making me happy. The error message looks quite straightforward, and it points me to the Not2
template. It complains that there is no Apply
member, but it clearly has Apply
, two of them. Function2
and Not2
has a very similar form, but the compiler doesn't say anything about Function2
, so something's going wrong inside Not2
. Not2
is meant to take a Function2
template and negate the result.
I removed irrelevant code as much as possible, but still the code seems quite long. Just skip away if you think reading all that isn't worth your time.
main.cpp:130:24: error: type/value mismatch at argument 1 in template parameter list for 'template<class T> constexpr const int unbox<T>'
using Apply = Box<!unbox<T::template Apply<U>::template Apply<V>>>;
^
main.cpp:130:24: note: expected a type, got 'typename T::Apply<U>::Apply<V>'
main.cpp:130:70: error: template argument 1 is invalid
using Apply = Box<!unbox<T::template Apply<U>::template Apply<V>>>;
^
main.cpp: In instantiation of 'struct Sort_<List<Box<2>, Box<1> > >':
main.cpp:155:37: required by substitution of 'template<class T> using Sort = typename Sort_::Type [with T = List<Box<2>, Box<1> >]'
main.cpp:159:38: required from here
main.cpp:151:77: error: no class template named 'Apply' in 'Not2<Function2<LessThan_> >::Apply<Box<2> > {aka struct Not2<Function2<LessThan_> >::Apply_<Box<2> >}'
Filter<Tail<T>, Not2<LessThan>::template Apply<Head<T>>::template Apply>> Type;
^
template<int n>
struct Box
{
};
template<typename T>
struct Unbox_;
template<int n>
struct Unbox_<Box<n>>
{
static constexpr int value = n;
};
template<typename T>
constexpr int unbox = Unbox_<T>::value;
template<typename ...>
struct List
{
};
template<>
struct List<>
{
};
template<typename, typename>
struct Cons_;
template<typename T, typename ...Ts>
struct Cons_<T, List<Ts...>>
{
typedef List<T, Ts...> Type;
};
template<typename T, typename U>
using Cons = typename Cons_<T, U>::Type;
template<typename>
struct Head_;
template<typename T, typename ...Ts>
struct Head_<List<T, Ts...>>
{
typedef T Type;
};
template<typename T>
using Head = typename Head_<T>::Type;
template<typename>
struct Tail_;
template<typename T, typename ...Ts>
struct Tail_<List<T, Ts...>>
{
typedef List<Ts...> Type;
};
template<typename T>
using Tail = typename Tail_<T>::Type;
template<typename T, typename U>
struct Merge_
{
typedef Cons<Head<T>, typename Merge_<Tail<T>, U>::Type> Type;
};
template<typename T>
struct Merge_<List<>, T>
{
typedef T Type;
};
template<typename T, typename U>
using Merge = typename Merge_<T, U>::Type;
template<typename, typename T, typename>
struct If_
{
typedef T Type;
};
template<typename T, typename U>
struct If_<Box<0>, T, U>
{
typedef U Type;
};
template<typename T, typename U, typename V>
using If = typename If_<T, U, V>::Type;
template<typename T, template<typename> class U>
struct Filter_
{
typedef If<U<Head<T>>, Cons<Head<T>, typename Filter_<Tail<T>, U>::Type>,
typename Filter_<Tail<T>, U>::Type> Type;
};
template<template<typename> class T>
struct Filter_<List<>, T>
{
typedef List<> Type;
};
template<typename T, template<typename> class U>
using Filter = typename Filter_<T, U>::Type;
template<template<typename, typename> class T>
struct Function2
{
template<typename U>
struct Apply_
{
template<typename V>
using Apply = T<U, V>;
};
template<typename U>
using Apply = Apply_<U>;
};
template<typename T>
struct Not2
{
template<typename U>
struct Apply_
{
template<typename V>
using Apply = Box<!unbox<T::template Apply<U>::template Apply<V>>>;
};
template<typename U>
using Apply = Apply_<U>;
};
template<typename T, typename U>
struct LessThan_2
{
typedef Box<unbox<T> < unbox<U>> Type;
};
template<typename T, typename U>
using LessThan_ = typename LessThan_2<T, U>::Type;
using LessThan = Function2<LessThan_>;
template<typename T>
struct Sort_
{
typedef Merge<Merge<Filter<Tail<T>, LessThan::Apply<Head<T>>::template Apply>, List<Head<T>>>,
Filter<Tail<T>, Not2<LessThan>::template Apply<Head<T>>::template Apply>> Type;
};
template<typename T>
using Sort = typename Sort_<T>::Type;
int main()
{
typedef Sort<List<Box<2>, Box<1>>> L;
}