Menu

problem with metaprogramming

Help
Omer Katz
2006-03-18
2013-04-08
  • Omer Katz

    Omer Katz - 2006-03-18

    Hi,

    I'm bored and I'm trying to make a java-like 'interface' on c++. If I'll finish it I'll submit it to Loki :P

    Now for some reason it gives me errors.

    Here is the code:

    #include <iostream>

    #include <loki/Sequence.h>

    #include <loki/Typelist.h>

    using namespace std;

    using namespace Loki;

    using namespace Loki::TL;

    template <typename Func, int Scope>

    class FunctionTraits

    {

    public:

                enum { FuncScope = -1 };

    };

    template <typename Func>

    class FunctionTraits<Func, 1>

    {

    protected:

                typedef Func FuncType;

    public:

                enum { FuncScope = 1 };

    };

    template <typename Func>

    class FunctionTraits<Func, 2>

    {

    public:

                typedef Func FuncType;

                enum { FuncScope = 2 };

    };

    template <class TL>

    class interface;

    template <typename Func1>

    class interface<Seq<Func1> > : public Func1

    {

    public:

                typedef Func1 F1;

    };

    template <typename Func1, typename Func2>

    class interface<Seq<Func1, Func2> > : public Func1, Func2

    {

    public:

                typedef Func1 F1;

                typedef Func2 F2;

    };

    template <typename Func1, typename Func2, typename Func3>

    class interface<Seq<Func1, Func2, Func3> > : public Func1, Func2, Func3

    {

    public:

                typedef Func1 F1;

                typedef Func2 F2;

                typedef Func3 F3;

    };

    template <typename Func1, typename Func2, typename Func3, typename Func4>

    class interface<Seq<Func1, Func2, Func3, Func4> > : public Func1, Func2, Func3, Func4

    {

    public:

                typedef Func1 F1;

                typedef Func2 F2;

                typedef Func3 F3;

                typedef Func4 F4;

    };

    template <typename Func1, typename Func2, typename Func3, typename Func4, typename Func5>

    class interface<Seq<Func1, Func2, Func3, Func4, Func5> > : public Func1, Func2, Func3, Func4, Func5

    {

    public:

                typedef Func1 F1;

                typedef Func2 F2;

                typedef Func3 F3;

                typedef Func4 F4;

                typedef Func5 F5;

    };

    class TestFunc

    {

    public:

                void operator() (int);

    };

    class TestFunc1

    {

    public:

                int operator() ();

    };

    class InterfaceTest

    {

                typedef interface<FunctionTraits<TestFunc, 2>, FunctionTraits<TestFunc1, 2> > myInterface; // ERROR HERE

    public:

                InterfaceTest() { }

    };

    int main()

    {

                cin.get();

      return 0;

       

    }

    main.cpp:95: error: wrong number of template arguments (2, should be 1)

    main.cpp:34: error: provided for `template<class TL> struct interface'

    main.cpp:95: error: ISO C++ forbids declaration of `myInterface' with no type

    But let's say I use only one function in the interface.

    Now InterfaceTest looks like this:

    class InterfaceTest

    {

                typedef interface<FunctionTraits<TestFunc, 2> > myInterface;

    public:

                InterfaceTest() { myInterface::F1::FuncType()(); }

    };

    It generates those errors:

    main.cpp: In constructor `InterfaceTest::InterfaceTest()':

    main.cpp:97: error: `struct interface<FunctionTraits<TestFunc, 2> >::F1' has not been declared

    main.cpp:97: error: `FuncType' undeclared (first use this function)

    main.cpp:97: error: (Each undeclared identifier is reported only once for each function it appears in.)

    Do you have any idea why?

    Omer.

     
    • Peter Kuemmel

      Peter Kuemmel - 2006-03-18

      You've defined the interface template with only one parameter:

      template <class TL>
      class interface;

      but at the error line there are two parameters.

       
      • Omer Katz

        Omer Katz - 2006-03-18

        But when you guys implented Functor you did the same.
        "    template <typename R, class TList,
                template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
            class FunctorImpl;"
        "    template <typename R, typename P1, typename P2,
                template <class, class> class ThreadingModel>
            class FunctorImpl<R, Seq<P1, P2>, ThreadingModel>
                : public Private::FunctorImplBase<R, ThreadingModel>
            {
            public:
                typedef R ResultType;
                typedef typename TypeTraits<P1>::ParameterType Parm1;
                typedef typename TypeTraits<P2>::ParameterType Parm2;
                virtual R operator()(Parm1, Parm2) = 0;
            };"
        In the second case there are more parameters and it still works.
        What about the second error?

        Omer.

         
        • Peter Kuemmel

          Peter Kuemmel - 2006-03-18

          No, in both cases there are three parameters.
          This is the importand line:

          class FunctorImpl<R, Seq<P1, P2>, ThreadingModel>

          All the P1,P2... are necessary to construct the second parameter>:

          1. R
          2. TList=Seq<P1,P2> -> this is ONE Parameter
          3. ThreadingModel

           
          • Omer Katz

            Omer Katz - 2006-03-18

            But isn't that what I did?
            "template <typename R, typename P1, typename P2, 
            template <class, class> class ThreadingModel>
            class FunctorImpl<R, Seq<P1, P2>, ThreadingModel> "

            I used Seq too.

             
            • Peter Kuemmel

              Peter Kuemmel - 2006-03-18

              No, in the line with the error is no Seq used:

              typedef interface<FunctionTraits<TestFunc, 2>, FunctionTraits<TestFunc1, 2> > myInterface; // ERROR HERE

              Only when there a Seq is used it matches
              1. with the general template definition of interface
              2. it matches your specialization for Seq<P1,P2>

               
              • Omer Katz

                Omer Katz - 2006-03-19

                Ok I get what was wrong.
                Now why can't I access FuncType?

                Omer.

                 
                • Omer Katz

                  Omer Katz - 2006-03-19

                  It works without FunctionTraits but I can't give up on it because I need the ScopeType to change the scope.
                  Btw what is the difference between Seq & MakeTypelist?

                  Omer

                   
                  • Peter Kuemmel

                    Peter Kuemmel - 2006-03-21

                    There are some specializations for Seq (Factory, Functor). And maybe there is also a compiler speed advantage for Seq because of less recursion.

                     
    • Peter Kuemmel

      Peter Kuemmel - 2006-03-18

      And Functor also takes only three types (the last one has a default value):

      Functor<void, Seq<int,int,int> >

       
    • Peter Kuemmel

      Peter Kuemmel - 2006-03-18

      So you must pass a Sequence:

      typedef interface<Seq<FunctionTraits<TestFunc, 2>, FunctionTraits<TestFunc1,2> > > myInterface; // ERROR HERE

       

Log in to post a comment.