0

Currently using C++20, GCC 11.1.0.

I'm trying to create types in a namespace with a unique value and name. I came up with this structure specifically to be able to access the variables with the scope resolution operator like so: foo::bar::name. However, I have no idea how to initialize the name variable. I tried adding a second non-type parameter const char* barName, but it wouldn't let me use string literals as template arguments.

Code:

namespace foo
{
    template<uint32_t id>
    struct bar
    {
        static constexpr uint32_t value {id};
        static constexpr std::string_view name {};
    };

    using a = bar<0>;
    using b = bar<1>;
}

Error Code:

namespace foo
{
    template<uint32_t id, const char* barName>
    struct bar
    {
        static constexpr uint32_t value {id};
        static constexpr std::string_view name {barName};
    };

    using a = bar<0, "a">;
    using b = bar<1, "b">;
}
spaL
  • 604
  • 7
  • 21
  • Do you get any error? String literals can't be template arguments. [Passing a string literal as a type argument to a class template](https://stackoverflow.com/questions/2033110/passing-a-string-literal-as-a-type-argument-to-a-class-template) – Jason Oct 09 '22 at 07:11
  • @JasonLiam Yea it tells me that string literals can't be template arguments. – spaL Oct 09 '22 at 07:12
  • Did you try searching. There are a lot of SO posts for this. – Jason Oct 09 '22 at 07:15
  • @JasonLiam I did. They say string literals don't work, or at least there were proposals for template argument string literals but it was rejected. But is there really no other way to initialize the `name` variable? – spaL Oct 09 '22 at 07:16
  • The `name` data member is already initialized when you wrote `static constexpr std::string_view name {}`. – Jason Oct 09 '22 at 07:17
  • @JasonLiam I mean specifying an initialization value for `name`, just like what I'm doing with `value`. – spaL Oct 09 '22 at 07:27
  • Why don't you just write `static constexpr std::string_view name {"somestring"};`? It will work. You should post the code the reproduces your problem and not the code that works. Or you can post both of them but you should definitely post the code that produces the error. Although i get the reason for the error(which is that you can't pass string literal as template argument for the second template parameter), there might be some to whom the error might not be obvious, so you should always post the code that produces the error. – Jason Oct 09 '22 at 07:31
  • @JasonLiam because I need a unique `value` and unique `name` for each type. E.g. `using a = bar<0, "a">;` and `using b = bar<0, "b">;` – spaL Oct 09 '22 at 07:35
  • @JasonLiam I've added the error code like you asked. – spaL Oct 09 '22 at 07:40
  • See the [answer](https://stackoverflow.com/a/74002932/12002570) below. It uses a static const char array. – Jason Oct 09 '22 at 07:42

1 Answers1

1

Since we can't pass string literals as template arguments, we have to use some other way. In particular, we can have a static const char array variable as shown below:

static constexpr char ch1[] = "somestrnig";
static constexpr char ch2[] = "anotherstring";
namespace foo
{   //--------------------vvvvvvvvvvvvvvvv--->added this 2nd template parameter
    template<uint32_t id, const char* ptr>
    struct bar
    {
        static constexpr uint32_t value {id};
        //--------------------------------------vvvv-->added this
        static constexpr std::string_view name {ptr};
    };
    //---------------vvv----->added this
    using a = bar<0, ch1>;
    using b = bar<1, ch2>;
}
Jason
  • 36,170
  • 5
  • 26
  • 60