Templates with constant array parameter

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kristian Bisgaard Lassen

    Templates with constant array parameter

    Hi,

    How do I parameterize a template by a a allocated array of integers,
    which is declared static and constant, so I can make compile time
    optimizations depending on the content of the array. The way I have
    written my code makes g++ complain about it not being static.

    BTW I am new to the C++ language and also the templates it provides.

    Here is an example of what I want to do

    template<bool condition, class Then, class Else>
    struct IF {
    typedef Then RET;
    };

    template<class Then, class Else>
    struct IF<false, Then, Else> {
    typedef Else RET;
    };

    struct A {
    static void exec () {
    cout << "yes" << endl;
    }
    };

    struct B {
    static void exec () {
    cout << "no" << endl;
    }
    };

    template<const int mask[]>
    void foo () {
    IF<mask[0] == 1,
    A,
    B>::RET::exec ();
    }

    struct Run {
    static void run () {
    static const int filter[] = {1,1,1};

    foo<filter>();
    }
    };

    int main () {
    Run::run();

    return 0;
    }

    I want the compiled code just to contain the instructions for

    cout << "yes" << endl;

    But as I said g++ complains and says

    error: non-constant `((*&filter) == 1)' cannot be used as template
    argument

    The error is from the statement

    IF<mask[0] == 1,
    A,
    B>::RET::exec ();

    Hope their is someone who can tell me what I am doing wrong or if is
    even possible make compiletime optimizations using arrays.

    Best regards,
    Kristian Bisgaard Lassen

  • Kristian Bisgaard Lassen

    #2
    Re: Templates with constant array parameter

    Hi,

    I have found out that the modifier const on int* only promises that the
    reference does not change. What it points to is not constant. Can you
    make some sort of declearation so an array ints = {1,1,1} is constant
    also on the content level? Ie. ints is statically an array of {1,1,1}.
    That is basically what I need to make the example work.

    An alternativ solution would be to use a pair, where the head of each
    pair is an constant integer. But I would really like to use an array
    somehow since it is a very convenient whay to specify a dataset.

    Best regards,
    Kristian Bisgaard Lassen

    Comment

    • Kristian Bisgaard Lassen

      #3
      Re: Templates with constant array parameter

      Hi,

      I have found out that the modifier const on int* only promises that the
      reference does not change. What it points to is not constant. Can you
      make some sort of declearation so an array ints = {1,1,1} is constant
      also on the content level? Ie. ints is statically an array of {1,1,1}.
      That is basically what I need to make the example work.

      An alternativ solution would be to use a pair, where the head of each
      pair is an constant integer. But I would really like to use an array
      somehow since it is a very convenient whay to specify a dataset.

      Best regards,
      Kristian Bisgaard Lassen

      Comment

      • Jeff Schwab

        #4
        Re: Templates with constant array parameter

        Kristian Bisgaard Lassen wrote:
        [color=blue]
        > How do I parameterize a template by a a allocated array of integers,
        > which is declared static and constant, so I can make compile time
        > optimizations depending on the content of the array. The way I have
        > written my code makes g++ complain about it not being static.[/color]

        The value of a boolean expression used as a tempate argument must be
        determined at compile time. Even when enough information is available
        to determine the value (as in the example code you posted), the compiler
        may fail to do so. Sorry to be the bearer of bad news. :(

        Comment

        • Jeff Schwab

          #5
          Re: Templates with constant array parameter

          Kristian Bisgaard Lassen wrote:
          [color=blue]
          > How do I parameterize a template by a a allocated array of integers,
          > which is declared static and constant, so I can make compile time
          > optimizations depending on the content of the array. The way I have
          > written my code makes g++ complain about it not being static.[/color]

          The value of a boolean expression used as a tempate argument must be
          determined at compile time. Even when enough information is available
          to determine the value (as in the example code you posted), the compiler
          may fail to do so. Sorry to be the bearer of bad news. :(

          Comment

          • Jeff Schwab

            #6
            Re: Templates with constant array parameter

            Kristian Bisgaard Lassen wrote:[color=blue]
            > Hi,
            >
            > I have found out that the modifier const on int* only promises that the
            > reference does not change. What it points to is not constant. Can you
            > make some sort of declearation so an array ints = {1,1,1} is constant
            > also on the content level? Ie. ints is statically an array of {1,1,1}.
            > That is basically what I need to make the example work.[/color]

            int const * const; // constant pointer to constant int
            int const *; // pointer to constant int
            int * const; // constant pointer to int.
            int *; // pointer to int

            Comment

            • Jeff Schwab

              #7
              Re: Templates with constant array parameter

              Kristian Bisgaard Lassen wrote:[color=blue]
              > Hi,
              >
              > I have found out that the modifier const on int* only promises that the
              > reference does not change. What it points to is not constant. Can you
              > make some sort of declearation so an array ints = {1,1,1} is constant
              > also on the content level? Ie. ints is statically an array of {1,1,1}.
              > That is basically what I need to make the example work.[/color]

              int const * const; // constant pointer to constant int
              int const *; // pointer to constant int
              int * const; // constant pointer to int.
              int *; // pointer to int

              Comment

              • Kristian Bisgaard Lassen

                #8
                Re: Templates with constant array parameter

                Hi Jeff,
                [color=blue]
                > The value of a boolean expression used as a tempate argument must be
                > determined at compile time.[/color]

                Yes that is also what I want.
                [color=blue]
                > Even when enough information is available
                > to determine the value (as in the example code you posted), the compiler
                > may fail to do so.[/color]

                Why is that? Is it my C++ compiler, g++? Or is it because I have not
                written the code so the compiler recognises it as being static? Ie. I
                have only declared the pointer to be constant.

                Best regards,
                Kristian Bisgaard Lassen

                Comment

                • Kristian Bisgaard Lassen

                  #9
                  Re: Templates with constant array parameter

                  Hi Jeff,
                  [color=blue]
                  > The value of a boolean expression used as a tempate argument must be
                  > determined at compile time.[/color]

                  Yes that is also what I want.
                  [color=blue]
                  > Even when enough information is available
                  > to determine the value (as in the example code you posted), the compiler
                  > may fail to do so.[/color]

                  Why is that? Is it my C++ compiler, g++? Or is it because I have not
                  written the code so the compiler recognises it as being static? Ie. I
                  have only declared the pointer to be constant.

                  Best regards,
                  Kristian Bisgaard Lassen

                  Comment

                  • tom_usenet

                    #10
                    Re: Templates with constant array parameter

                    On Wed, 07 Apr 2004 13:14:48 +0200, Kristian Bisgaard Lassen
                    <krell@daimi.au .dk> wrote:
                    [color=blue]
                    >Hi,
                    >
                    >How do I parameterize a template by a a allocated array of integers,
                    >which is declared static and constant, so I can make compile time
                    >optimization s depending on the content of the array. The way I have
                    >written my code makes g++ complain about it not being static.
                    >
                    >BTW I am new to the C++ language and also the templates it provides.[/color]

                    This is quite advanced for someone who is new to the language!
                    [color=blue]
                    >template<con st int mask[]>
                    >void foo () {
                    > IF<mask[0] == 1,
                    > A,
                    > B>::RET::exec ();
                    >}[/color]

                    As you've seen, that's illegal - performing an array lookup isn't a
                    compile time operation. The contents of arrays (const literal or not)
                    are never known to the compiler at compile time except where the array
                    is initialised.
                    [color=blue]
                    >I want the compiled code just to contain the instructions for
                    >
                    > cout << "yes" << endl;[/color]

                    That is possible, using recursive lists of integers rather than
                    arrays. Two versions (both tested with GCC and Comeau C++) below:

                    #include <iostream>
                    using namespace std;

                    template<bool condition, class Then, class Else>
                    struct IF {
                    typedef Then RET;
                    };

                    template<class Then, class Else>
                    struct IF<false, Then, Else> {
                    typedef Else RET;
                    };

                    struct A {
                    static void exec () {
                    cout << "yes" << endl;
                    }
                    };

                    struct B {
                    static void exec () {
                    cout << "no" << endl;
                    }
                    };

                    template <int i, class Tail>
                    struct IntList
                    {
                    static int const value = i;
                    typedef Tail tail;
                    };

                    struct null_type{};

                    template <int i, class List>
                    struct AtIndex
                    {
                    typedef typename AtIndex<i - 1, typename List::tail>::ty pe type;
                    };

                    template <class List>
                    struct AtIndex<0, List>
                    {
                    typedef List type;
                    };

                    template<class IntList>
                    void foo () {
                    IF<AtIndex<0, IntList>::type: :value == 1,
                    A,
                    B>::RET::exec ();
                    }

                    struct Run {
                    static void run () {
                    foo<IntList<1, IntList<1, IntList<1, null_type> > > >();
                    }
                    };

                    int main () {
                    Run::run();

                    return 0;
                    }


                    Or using boost's MPL library (www.boost.org):

                    #include <boost/mpl/if.hpp>
                    #include <boost/mpl/vector_c.hpp>
                    #include <boost/mpl/at.hpp>
                    using namespace boost::mpl;

                    #include <iostream>
                    using namespace std;

                    struct A {
                    static void exec () {
                    cout << "yes" << endl;
                    }
                    };

                    struct B {
                    static void exec () {
                    cout << "no" << endl;
                    }
                    };

                    template<class List>
                    void foo () {
                    if_c<
                    at_c<List, 0>::type::valu e == 1,
                    A,
                    B[color=blue]
                    >::type::exec() ;[/color]
                    }

                    struct Run {
                    static void run () {
                    foo<vector_c<in t, 1, 1, 1> >();
                    }
                    };

                    int main () {
                    Run::run();

                    return 0;
                    }

                    Tom
                    --
                    C++ FAQ: http://www.parashift.com/c++-faq-lite/
                    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

                    Comment

                    • tom_usenet

                      #11
                      Re: Templates with constant array parameter

                      On Wed, 07 Apr 2004 13:14:48 +0200, Kristian Bisgaard Lassen
                      <krell@daimi.au .dk> wrote:
                      [color=blue]
                      >Hi,
                      >
                      >How do I parameterize a template by a a allocated array of integers,
                      >which is declared static and constant, so I can make compile time
                      >optimization s depending on the content of the array. The way I have
                      >written my code makes g++ complain about it not being static.
                      >
                      >BTW I am new to the C++ language and also the templates it provides.[/color]

                      This is quite advanced for someone who is new to the language!
                      [color=blue]
                      >template<con st int mask[]>
                      >void foo () {
                      > IF<mask[0] == 1,
                      > A,
                      > B>::RET::exec ();
                      >}[/color]

                      As you've seen, that's illegal - performing an array lookup isn't a
                      compile time operation. The contents of arrays (const literal or not)
                      are never known to the compiler at compile time except where the array
                      is initialised.
                      [color=blue]
                      >I want the compiled code just to contain the instructions for
                      >
                      > cout << "yes" << endl;[/color]

                      That is possible, using recursive lists of integers rather than
                      arrays. Two versions (both tested with GCC and Comeau C++) below:

                      #include <iostream>
                      using namespace std;

                      template<bool condition, class Then, class Else>
                      struct IF {
                      typedef Then RET;
                      };

                      template<class Then, class Else>
                      struct IF<false, Then, Else> {
                      typedef Else RET;
                      };

                      struct A {
                      static void exec () {
                      cout << "yes" << endl;
                      }
                      };

                      struct B {
                      static void exec () {
                      cout << "no" << endl;
                      }
                      };

                      template <int i, class Tail>
                      struct IntList
                      {
                      static int const value = i;
                      typedef Tail tail;
                      };

                      struct null_type{};

                      template <int i, class List>
                      struct AtIndex
                      {
                      typedef typename AtIndex<i - 1, typename List::tail>::ty pe type;
                      };

                      template <class List>
                      struct AtIndex<0, List>
                      {
                      typedef List type;
                      };

                      template<class IntList>
                      void foo () {
                      IF<AtIndex<0, IntList>::type: :value == 1,
                      A,
                      B>::RET::exec ();
                      }

                      struct Run {
                      static void run () {
                      foo<IntList<1, IntList<1, IntList<1, null_type> > > >();
                      }
                      };

                      int main () {
                      Run::run();

                      return 0;
                      }


                      Or using boost's MPL library (www.boost.org):

                      #include <boost/mpl/if.hpp>
                      #include <boost/mpl/vector_c.hpp>
                      #include <boost/mpl/at.hpp>
                      using namespace boost::mpl;

                      #include <iostream>
                      using namespace std;

                      struct A {
                      static void exec () {
                      cout << "yes" << endl;
                      }
                      };

                      struct B {
                      static void exec () {
                      cout << "no" << endl;
                      }
                      };

                      template<class List>
                      void foo () {
                      if_c<
                      at_c<List, 0>::type::valu e == 1,
                      A,
                      B[color=blue]
                      >::type::exec() ;[/color]
                      }

                      struct Run {
                      static void run () {
                      foo<vector_c<in t, 1, 1, 1> >();
                      }
                      };

                      int main () {
                      Run::run();

                      return 0;
                      }

                      Tom
                      --
                      C++ FAQ: http://www.parashift.com/c++-faq-lite/
                      C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

                      Comment

                      • Jeff Schwab

                        #12
                        Re: Templates with constant array parameter

                        Kristian Bisgaard Lassen wrote:[color=blue]
                        > Hi Jeff,
                        >[color=green]
                        >> The value of a boolean expression used as a tempate argument must be
                        >> determined at compile time.[/color]
                        >
                        >
                        > Yes that is also what I want.
                        >[color=green]
                        >> Even when enough information is available to determine the value (as
                        >> in the example code you posted), the compiler may fail to do so.[/color]
                        >
                        >
                        > Why is that? Is it my C++ compiler, g++? Or is it because I have not
                        > written the code so the compiler recognises it as being static? Ie. I
                        > have only declared the pointer to be constant.[/color]

                        The post from tom_usenet on this thread explains quite eloquently. :)

                        If you want to get into metaprogramming , check out the Josuttis book on
                        templates. It was an eye opener for me.

                        Comment

                        • Jeff Schwab

                          #13
                          Re: Templates with constant array parameter

                          Kristian Bisgaard Lassen wrote:[color=blue]
                          > Hi Jeff,
                          >[color=green]
                          >> The value of a boolean expression used as a tempate argument must be
                          >> determined at compile time.[/color]
                          >
                          >
                          > Yes that is also what I want.
                          >[color=green]
                          >> Even when enough information is available to determine the value (as
                          >> in the example code you posted), the compiler may fail to do so.[/color]
                          >
                          >
                          > Why is that? Is it my C++ compiler, g++? Or is it because I have not
                          > written the code so the compiler recognises it as being static? Ie. I
                          > have only declared the pointer to be constant.[/color]

                          The post from tom_usenet on this thread explains quite eloquently. :)

                          If you want to get into metaprogramming , check out the Josuttis book on
                          templates. It was an eye opener for me.

                          Comment

                          Working...