Array template parameters

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Rade

    #1

    Array template parameters

    Please have a look at the following program:

    #include <iostream>

    template <const int array[], size_t index>
    class ArrayIndex
    {
    public:
    static const int value = array[index];
    };

    extern const int array[] = { 1, 2, 3, 4, 5 };

    int main()
    {
    std::cout <<
    ArrayIndex<arra y, 0>::value << "," <<
    ArrayIndex<arra y, 1>::value << "," <<
    ArrayIndex<arra y, 2>::value << "," <<
    ArrayIndex<arra y, 3>::value << "," <<
    ArrayIndex<arra y, 4>::value;
    }

    Output is, on my C++ compiler (VS 2003): 0,0,0,0,0 while I'd expect that the
    output is 1,2,3,4,5. What actually does the C++ Standard say about this? In
    other words, is the above program correct and if it is, what should be its
    output with a standard-compliant compiler ? Moreover, if the program is
    correct, is the expression 'array[index]' within the ArrayIndex class
    regarded as a constant expression ?

    (note that I had to declare the array with 'extern', which shouldn't be
    necessary by the Standard, as this array has external linkage, anyway.
    However, the compiler issues an error if I don't do this. So I have reasons
    to suspect that the compiler is not standard-compliant).

    Regards,
    Rade



  • serock

    #2
    Re: Array template parameters

    template <const int array[], size_t index>
    class ArrayIndex
    {
    public:
    static const int value;
    };

    template <const int array[], size_t index>
    const int ArrayIndex<arra y, index>::value = array[index];
    -----------------------------------------------------------------
    Static member definition should be separated from its declaration.

    Comment

    • Siemel Naran

      #3
      Re: Array template parameters

      "serock" <s.rock.e@gmail .com> wrote in message
      [color=blue]
      > template <const int array[], size_t index>
      > class ArrayIndex
      > {
      > public:
      > static const int value;
      > };
      >
      > template <const int array[], size_t index>
      > const int ArrayIndex<arra y, index>::value = array[index];
      > -----------------------------------------------------------------
      > Static member definition should be separated from its declaration.[/color]

      This is not required for static const integral types (int, char, bool, long,
      short). I think the OP's code is legal, though my version of g++ and
      Borland both complain.


      Comment

      • Rob Williscroft

        #4
        Re: Array template parameters

        Siemel Naran wrote in
        news:oZJsd.9341 5$7i4.16403@bgt nsc05-news.ops.worldn et.att.net in
        comp.lang.c++:
        [color=blue]
        > "serock" <s.rock.e@gmail .com> wrote in message
        >[color=green]
        >> template <const int array[], size_t index>
        >> class ArrayIndex
        >> {
        >> public:
        >> static const int value;
        >> };
        >>
        >> template <const int array[], size_t index>
        >> const int ArrayIndex<arra y, index>::value = array[index];
        >> -----------------------------------------------------------------
        >> Static member definition should be separated from its declaration.[/color]
        >
        > This is not required for static const integral types (int, char, bool,
        > long, short). I think the OP's code is legal, though my version of
        > g++ and Borland both complain.
        >
        >[/color]

        The problem is that the initializer "array[ index ]" *isn't* a
        compile time constant (intergral constant expression).

        IOW, the out of class initialization is required.

        Rob.
        --

        Comment

        • Siemel Naran

          #5
          Re: Array template parameters

          "Rob Williscroft" <rtw@freenet.co .uk> wrote in message[color=blue]
          > Siemel Naran wrote in[/color]
          [color=blue][color=green]
          > > This is not required for static const integral types (int, char, bool,
          > > long, short). I think the OP's code is legal, though my version of
          > > g++ and Borland both complain.[/color]
          >
          > The problem is that the initializer "array[ index ]" *isn't* a
          > compile time constant (intergral constant expression).
          >
          > IOW, the out of class initialization is required.[/color]

          Do you have a quote from the standard? I agree that if if 'array' has type
          "int *" then array[3] is not an integral constant, but if it has type "int
          const *" then array[3] should be a constant so long as array itself is
          constant, which is the case because it is extern const.

          In any case, I made the initialization out of line for g++ to compile it,
          and I still witness the original behavior that it prints "0,0,0,0,0, "
          instead of "1,2,3,4,5, ". Strange. Yet when I force the instantiation of
          the specific classes by using template class, it does work. Stranger.


          Comment

          • Siemel Naran

            #6
            Re: Array template parameters

            "Rade" <no.such.addres s@btinternet.co m> wrote in message news:covce2$e84
            [color=blue]
            > #include <iostream>
            >
            > template <const int array[], size_t index>
            > class ArrayIndex
            > {
            > public:
            > static const int value = array[index];
            > };
            >
            > extern const int array[] = { 1, 2, 3, 4, 5 };
            >
            > int main()
            > {
            > std::cout <<
            > ArrayIndex<arra y, 0>::value << "," <<
            > ArrayIndex<arra y, 1>::value << "," <<
            > ArrayIndex<arra y, 2>::value << "," <<
            > ArrayIndex<arra y, 3>::value << "," <<
            > ArrayIndex<arra y, 4>::value;
            > }
            >
            > Output is, on my C++ compiler (VS 2003): 0,0,0,0,0 while I'd expect that[/color]
            the[color=blue]
            > output is 1,2,3,4,5.[/color]

            This is quite strange. I added statements to force the compiler to
            instantiate the ArraynIndex classes, and it works now, at least on g++
            2.95.2-6. Add the five lines (without >) to your program and see if it
            works.
            [color=blue]
            > extern const int array[] = { 1, 2, 3, 4, 5 };[/color]

            template class ArrayIndex<arra y, 0>;
            template class ArrayIndex<arra y, 1>;
            template class ArrayIndex<arra y, 2>;
            template class ArrayIndex<arra y, 3>;
            template class ArrayIndex<arra y, 4>;
            [color=blue]
            >
            > int main()[/color]

            [color=blue]
            > What actually does the C++ Standard say about this? In
            > other words, is the above program correct and if it is, what should be its
            > output with a standard-compliant compiler ? Moreover, if the program is
            > correct, is the expression 'array[index]' within the ArrayIndex class
            > regarded as a constant expression ?[/color]

            Seems to me array[index] is an integral expression because array has type T
            const *const, but don't know what the standard says.
            [color=blue]
            > (note that I had to declare the array with 'extern', which shouldn't be
            > necessary by the Standard, as this array has external linkage, anyway.
            > However, the compiler issues an error if I don't do this. So I have[/color]
            reasons[color=blue]
            > to suspect that the compiler is not standard-compliant).[/color]

            Const objects have internal linkage by default, so the extern is necessary.


            Comment

            • Rade

              #7
              Re: Array template parameters

              > Static member definition should be separated from its declaration.

              OK, it's better now, but does C++ language require it, or the requirement
              comes from Microsoft ?

              As far as I know, one should be able to define static consts inside the
              class as well as outside, as long as they are initialized by a constant
              expression. That's why I asked about whether array[index] is regarded as a
              constant expression in this context. If it is constant, then my code should
              work (but it doesn't). If it is not constant, then the compiler should have
              warned me that I was trying to initialize a static const within a class with
              a nonconstant expression (but it hasn't). Am I right ?

              Rade


              Comment

              • Rob Williscroft

                #8
                Re: Array template parameters

                Siemel Naran wrote in
                news:Z7Ksd.9344 7$7i4.30400@bgt nsc05-news.ops.worldn et.att.net in
                comp.lang.c++:
                [color=blue]
                > "Rob Williscroft" <rtw@freenet.co .uk> wrote in message[color=green]
                >> Siemel Naran wrote in[/color]
                >[color=green][color=darkred]
                >> > This is not required for static const integral types (int, char,
                >> > bool, long, short). I think the OP's code is legal, though my
                >> > version of g++ and Borland both complain.[/color]
                >>
                >> The problem is that the initializer "array[ index ]" *isn't* a
                >> compile time constant (intergral constant expression).
                >>
                >> IOW, the out of class initialization is required.[/color]
                >
                > Do you have a quote from the standard?[/color]

                5.19 & 5.2.1

                Rob.
                --

                Comment

                Working...