CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Aug 2009
    Posts
    81

    Unhappy Passing a string constant as a template argument

    I`m trying to pass a const char* paramater to a templatized class
    for example:
    template<const char* param>
    class A
    {
    ..
    };

    When I create new instance of A<"bla"> I get a compilation error:
    invalid expression as a template argument for 'param'

    Is there a way to pass a string constant as a template argument?

  2. #2
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863

    Re: Passing a string constant as a template argument

    the string you are passing as a template parameter needs to have external linkage and be named. You would need to explicitly declare a variable for the string

    const char[] bla = "bla";

    now use

    A<bla>
    Wakeup in the morning and kick the day in the teeth!! Or something like that.

    "i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Passing a string constant as a template argument


  4. #4
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Passing a string constant as a template argument

    You could also use the "multibyte character constant" trick, with the caveat that the maximum string length is implementation defined.

    anyway, if your compiler implementation supports 4-byte characters (if I remember well, this is equivalent to sizeof(int)==4) you could write

    Code:
    template <int name>
    class A {/**/};
    
    //...
    
    A<'bla'> x;

  5. #5
    Join Date
    Aug 2009
    Posts
    81

    Re: Passing a string constant as a template argument

    Quote Originally Posted by souldog View Post
    the string you are passing as a template parameter needs to have external linkage and be named. You would need to explicitly declare a variable for the string

    const char[] bla = "bla";

    now use

    A<bla>
    I have a problem with defining it that way, because I`m using it in a header file - so there might be multiple definitions of the same thing, and it is going to lead to linkage error. What can I do?
    I mean, I use something like this:

    myheader.h:
    template<const char* p>
    class A
    {
    ..
    };

    char[] bla = "bla";
    class B: public A<bla>
    {
    ..
    };

    can I avoid the problem of redefinition of bla ?
    Last edited by Regel; October 2nd, 2009 at 12:04 PM.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Passing a string constant as a template argument

    Quote Originally Posted by Regel View Post
    I have a problem with defining it that way, because I`m using it in a header file - so there will be multiple definitions of the same thing, and it is going to lead to linkage error.
    Yourheader.h
    Code:
    #ifdef GLOBAL_DEF 
    #define EXTERN_DEF
    #else
    #define EXTERN_DEF extern
    #endif
    //...
    EXTERN_DEF char whatever[10];
    //
    And in one and only one CPP module:
    Code:
    #define GLOBAL_DEF
    #include "YourHeader.h"
    
    // the rest of the code
    See how that works? In only one module will there be a global, while the other modules that will include yourheader.h will have it defined as extern.

    The trick is that only one module has the #define GLOBAL_DEF at the top of the source file. The other modules that will include "yourheader.h" won't have GLOBAL_DEF, so it will make "whatever" an extern variable.

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Aug 2009
    Posts
    81

    Re: Passing a string constant as a template argument

    Thank you Paul.
    Another question:
    Regarding to what souldog have said, I didn`t understand why the template paramater needs to have external linkage. Can you explain what makes it so crucial?

  8. #8
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863

    Re: Passing a string constant as a template argument

    instead of using the preprocessor tricks Paul has mentioned you can just place the declaration in an anonymous namespace to solve the linker problem. That is one of the things anonymous namespaces are for

    namespace
    {

    const char[] bla = "bla";

    }
    Wakeup in the morning and kick the day in the teeth!! Or something like that.

    "i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."

  9. #9
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863

    Re: Passing a string constant as a template argument

    template parameters must have external linkage to avoid multiple instantiations of a template class across translation unit boundaries
    Wakeup in the morning and kick the day in the teeth!! Or something like that.

    "i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."

  10. #10
    Join Date
    Aug 2009
    Posts
    81

    Re: Passing a string constant as a template argument

    souldog, I`m a person that loves to understand how things work. How does the anonymous namespace avoid the linkage errors behind the scences?
    EDIT:
    I think I`ve grapsed it, is this because namespace has external linkage by default, and const char[] has an internal linkage by default. then you combine both of them to prevent redefinition?

    and I haven`t realized yet why without external linkage there might be multiple instantiation of a template class accross translation units? may you give me an example?
    Last edited by Regel; October 2nd, 2009 at 01:00 PM.

  11. #11
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Passing a string constant as a template argument

    Quote Originally Posted by souldog View Post
    instead of using the preprocessor tricks Paul has mentioned you can just place the declaration in an anonymous namespace
    Yes.

    If the OP really insists on having "true" globals, the preprocessor trick is one way to keep the variables as global and have them easily maintained (source code wise) to some capacity.

    Mind you, I rarely, if ever, use globals in my own code. I haven't used that preprocessor trick in over 15 years.

    Regards,

    Paul McKenzie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured