Non-type variadic template parameter

Viewed 561

I want to make class with variadic wchar* value arguments. Consider the following example.

template<const wchar_t* ...properties>
class my_iterator{
public:
     std::tuple<std::wstring...> get(); // quantity of wstrings depend on quantity of template parameters
};

I want to use that like the following

my_iterator<L"hello", L"world"> inst(object_collection);
while(inst.next()){
    auto x = inst.get();
}

But I receive compile error, when I instantiate the class.

error C2762: 'my_iterator': invalid expression as a template argument for 'properties'

What's wrong and what to do?

3 Answers

This has nothing to do with the template parameter being variadic or non-type - string literals cannot simply be used as template parameters (until P0732 - which was accepted - becomes reality).

template <const char*> struct foo { };
foo<"hi"> x;

Will fail as well. live example on godbolt.org

error: '"hi"' is not a valid template argument for type 'const char*' because string literals can never be used in this context

What's wrong is [temp.arg.nontype] §2.3. String literals cannot (currently) be used as template arguments. What you could do, for example, is declare named array objects and use those as arguments:

template<const wchar_t* ...properties>
class my_iterator {};


int main()
{
    static constexpr const wchar_t a[] = L"hello";
    static constexpr const wchar_t b[] = L"world";

    my_iterator<a, b> inst;
}

working example here

Another alternative is to pass the characters one by one,

#include <tuple>

template<wchar_t ...properties>
class my_iterator{
public:
     std::tuple<decltype(properties)...> get(); // quantity of wstrings depend on quantity of template parameters
};

my_iterator<L'h', L'e',  L'l', L'l', L'o'> inst;
Related