2

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;
}
  • 1
    why do you have this complicated `unbox` construct rather than simply `Box::N`, (which needs to be declared as `static constexpr` member). – Walter Sep 08 '15 at 21:05
  • 1
    possible duplicate of [Officially, what is typename for?](http://stackoverflow.com/questions/1600936/officially-what-is-typename-for) – Walter Sep 08 '15 at 21:07
  • 1
    @Walter To look more like lisp. –  Sep 08 '15 at 21:20

1 Answers1

2

I believe you are simply missing a typename inside the unbox template argument list on the line (130) giving you the error.

Also, you do not seem to be doing any sorting in your Sort_ and Merge_ templates, since they simply concatenate lists using the head as pivot Coliru illustration. I guess your code is not completed yet.

Émilien Tlapale
  • 903
  • 5
  • 11
  • 1
    Finally completed including the printing function. http://coliru.stacked-crooked.com/a/ed2a3716c7771eae –  Sep 08 '15 at 21:19