Invalid template argument

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

    Invalid template argument

    Hello all,

    Okay, I've got a templated class that that takes an int and a char *, but
    when I try to instantiate an object of that template, VS.NET complains with:

    error C2975: 'S' : invalid template argument for 'TextDB::TextDB _Version',
    constant expression expected

    template<int N, char *S>
    class TextDB_Version
    {
    [...]
    };

    #define TDB_DEFAULT_DEL IMITER "."
    class TextDB
    {
    private:
    TextDB_Version< 3, TDB_DEFAULT_DEL IMITER> myVersion;
    };

    I can't understand what's wrong with this. It seems to me from
    documentation that I should be able to use char *'s as literal template
    arguments, what am I missing here? I tried taking out the #define and put
    in just a string there, TextDB_Version< 3, "."> myVersion; and that had the
    same error obviously.

    Thanks for everyone's time,
    Kevin Grigorenko


  • tom_usenet

    #2
    Re: Invalid template argument

    On Mon, 15 Sep 2003 12:57:44 -0400, "Kevin Grigorenko"
    <kzg110@psu.edu > wrote:
    [color=blue]
    >Hello all,
    >
    >Okay, I've got a templated class that that takes an int and a char *, but
    >when I try to instantiate an object of that template, VS.NET complains with:
    >
    >error C2975: 'S' : invalid template argument for 'TextDB::TextDB _Version',
    >constant expression expected
    >
    >template<int N, char *S>
    >class TextDB_Version
    >{
    > [...]
    >};
    >
    >#define TDB_DEFAULT_DEL IMITER "."
    >class TextDB
    >{
    >private:
    > TextDB_Version< 3, TDB_DEFAULT_DEL IMITER> myVersion;
    >};
    >
    >I can't understand what's wrong with this. It seems to me from
    >documentatio n that I should be able to use char *'s as literal template
    >arguments, what am I missing here? I tried taking out the #define and put
    >in just a string there, TextDB_Version< 3, "."> myVersion; and that had the
    >same error obviously.[/color]

    Literals don't have external linkage, but template parameters must. So
    you need:

    char* TDB_DEFAULT_DEL IMITER = "."; //has external linkage.

    class TextDB
    {
    private:
    TextDB_Version< 3, TDB_DEFAULT_DEL IMITER> myVersion;
    };

    Tom

    Comment

    • White Wolf

      #3
      Re: Invalid template argument

      tom_usenet wrote:[color=blue][color=green]
      >> error C2975: 'S' : invalid template argument for
      >> 'TextDB::TextDB _Version', constant expression expected[/color][/color]
      [SNIP][color=blue]
      > Literals don't have external linkage, but template parameters must. So
      > you need:
      >
      > char* TDB_DEFAULT_DEL IMITER = "."; //has external linkage.[/color]

      Is that really a compile time constant (required for template
      instantiation)?

      --
      WW aka Attila


      Comment

      • Gianni Mariani

        #4
        Re: Invalid template argument

        tom_usenet wrote:[color=blue]
        > On Mon, 15 Sep 2003 12:57:44 -0400, "Kevin Grigorenko"
        > <kzg110@psu.edu > wrote:[/color]

        .....
        [color=blue][color=green]
        >>
        >>template<in t N, char *S>
        >>class TextDB_Version
        >>{[/color][/color]
        ....
        [color=blue]
        >
        > Literals don't have external linkage, but template parameters must. So
        > you need:
        >
        > char* TDB_DEFAULT_DEL IMITER = "."; //has external linkage.
        >
        > class TextDB
        > {
        > private:
        > TextDB_Version< 3, TDB_DEFAULT_DEL IMITER> myVersion;
        > };
        >
        > Tom[/color]

        The alternative is to use a single char as a delimiter:

        template<int N, char D>

        like:

        TextDB_Version< 3, '.'>

        if you only have single character delimiters.

        Comment

        • Kevin Saff

          #5
          Re: Invalid template argument

          "Kevin Grigorenko" <kzg110@psu.edu > wrote in message
          news:bk4r2d$11a g$1@f04n12.cac. psu.edu...[color=blue]
          > Hello all,
          >
          > SNIP
          >
          > I can't understand what's wrong with this. It seems to me from
          > documentation that I should be able to use char *'s as literal template
          > arguments, what am I missing here? I tried taking out the #define and put
          > in just a string there, TextDB_Version< 3, "."> myVersion; and that had the
          > same error obviously.[/color]

          This is addressed many times in the archives (but not in the FAQ yet, it
          appears). I'm sure you can search google groups for the long answer. The
          short answer is char* is fine for template arguments, but you just can't
          create templates of the form TemplateClass<" text">. In this particular
          case, why don't you just declare your template as:

          template<int N, char S>
          class TextDB_Version
          {
          [...]
          };

          and then you can instantiate with

          TextDB_Version< 3, '.'>


          Comment

          • Kevin Grigorenko

            #6
            Re: Invalid template argument

            "Kevin Saff" <google.com@kev in.saff.net> wrote in message
            news:HL9psw.EtL @news.boeing.co m...[color=blue]
            > "Kevin Grigorenko" <kzg110@psu.edu > wrote in message
            > news:bk4r2d$11a g$1@f04n12.cac. psu.edu...[color=green]
            > > Hello all,
            > >
            > > SNIP
            > >
            > > I can't understand what's wrong with this. It seems to me from
            > > documentation that I should be able to use char *'s as literal template
            > > arguments, what am I missing here? I tried taking out the #define and[/color][/color]
            put[color=blue][color=green]
            > > in just a string there, TextDB_Version< 3, "."> myVersion; and that had[/color][/color]
            the[color=blue][color=green]
            > > same error obviously.[/color]
            >
            > This is addressed many times in the archives (but not in the FAQ yet, it
            > appears). I'm sure you can search google groups for the long answer. The
            > short answer is char* is fine for template arguments, but you just can't
            > create templates of the form TemplateClass<" text">. In this particular
            > case, why don't you just declare your template as:
            >
            > template<int N, char S>
            > class TextDB_Version
            > {
            > [...]
            > };
            >
            > and then you can instantiate with
            >
            > TextDB_Version< 3, '.'>
            >
            >[/color]

            I'm sorry about being a little bit oblivious, but where are the archives? I
            will use this suggestion however and just use one character.

            The interesting thing is that in the description of the error, VS.NET gives
            this as an example of how to fix it:

            // C2975.cpp
            template <char *P>
            class x
            {
            char * f()
            {
            return P;
            }
            };

            x<"abc"> *p = 0; // C2975 addr of object with internal linkage
            Is this standardized? Does it have something to do with "internal linkage,"
            which i must say i'm also oblivious about.

            Thanks again,
            Kevin Grigorenko


            Comment

            • Kevin Goodsell

              #7
              Re: Invalid template argument

              Kevin Grigorenko wrote:[color=blue]
              >
              > I'm sorry about being a little bit oblivious, but where are the archives?[/color]



              -Kevin
              --
              My email address is valid, but changes periodically.
              To contact me please use the address from a recent posting.

              Comment

              • Kevin Saff

                #8
                Re: Invalid template argument


                "Kevin Grigorenko" <kzg110@psu.edu > wrote in message
                news:bk52la$1e1 e$1@f04n12.cac. psu.edu...[color=blue]
                > I'm sorry about being a little bit oblivious, but where are the archives?[/color]
                I[color=blue]
                > will use this suggestion however and just use one character.[/color]

                Sorry, here's a link:


                and here are some posts you may be interested in:

                g.c%252B%252B.*

                [color=blue]
                >
                > The interesting thing is that in the description of the error, VS.NET[/color]
                gives[color=blue]
                > this as an example of how to fix it:
                >
                >
                > // C2975.cpp
                > template <char *P>
                > class x
                > {
                > char * f()
                > {
                > return P;
                > }
                > };
                >
                > x<"abc"> *p = 0; // C2975 addr of object with internal linkage
                >
                >
                > Is this standardized? Does it have something to do with "internal[/color]
                linkage,"[color=blue]
                > which i must say i'm also oblivious about.[/color]

                That looks like just an example of the error, rather than a fix. They're
                constructing a null pointer to a x<"abc"> object, but "abc" has internal
                linkage so isn't eligible for use as a template parameter.

                Internal linkage means the variable name can't be accessed in external
                compilation units. For one thing, note that x<"abc"> would at least
                represent a different class in a different compilation unit, because the
                address of the string will be different. This means at best the template
                class would have internal linkage as well. Still it seems like there could
                be use for such a thing; apparently the full reason template parameters
                cannot have internal linkage has something to do with how template names are
                required to be mangled.



                Comment

                • tom_usenet

                  #9
                  Re: Invalid template argument

                  On Mon, 15 Sep 2003 20:50:24 +0300, "White Wolf" <wolof@freemail .hu>
                  wrote:
                  [color=blue]
                  >tom_usenet wrote:[color=green][color=darkred]
                  >>> error C2975: 'S' : invalid template argument for
                  >>> 'TextDB::TextDB _Version', constant expression expected[/color][/color]
                  >[SNIP][color=green]
                  >> Literals don't have external linkage, but template parameters must. So
                  >> you need:
                  >>
                  >> char* TDB_DEFAULT_DEL IMITER = "."; //has external linkage.[/color]
                  >
                  >Is that really a compile time constant (required for template
                  >instantiation) ?[/color]

                  Whoops, that was meant to be:

                  char TDB_DEFAULT_DEL IMITER[] = "."; //has external linkage.

                  Tom

                  Comment

                  Working...