将模板参数包扩展为非类型模板参数

时间:2021-04-09 08:10:59

标签: c++ templates

我想在编译时对字符串做一些事情,所以我写了一个带有非类型参数的类。详情如下。

这是我的代码,由 Clang 11.0.1, C++20 编译

#include <type_traits>

// my non-type template parameters string class
template<char... str>
struct StaticString
{
    static constexpr char data[] = { str... };
};

// I will do something in this function, but now just return the character.
template<std::size_t N>
constexpr char nthChar(const char (&str)[N], std::size_t i) { return str[i]; }

// success to compile
inline constexpr char testNthChar = nthChar("xxx", 2);

template<std::size_t N, std::size_t... i>
constexpr auto makeStaticString(const char (&str)[N], std::index_sequence<i...>)
{
    return StaticString<nthChar(str, i)...>{};
    //                    ^~~~~~~~~~~~~~~
    // error: non-type template argument is not a constant expression
    // I tend to think that I made a mistake...
}

template<std::size_t N>
constexpr auto buildStr(const char(&str)[N])
{
    // make an index sequence that is used to provide an index to get chars in str
    return makeStaticString(str, std::make_index_sequence<N>{}).data;
}

extern const char sf[] = "1234";

void foo()
{
    constexpr auto ss = buildStr("0123");

    // not caused by internal linkage attribute
    // constexpr auto ssExtern = buildStr(sf);
}

完整的编译器错误:

[build] D:\LLVM\bin\clang++.exe   -g -Xclang -gcodeview -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -std=gnu++20 -MD -MT CMakeFiles/test.dir/test.cpp.obj -MF CMakeFiles\test.dir\test.cpp.obj.d -o CMakeFiles/test.dir/test.cpp.obj -c ../test.cpp
[build] ../test.cpp:21:22: error: non-type template argument is not a constant expression
[build]         return StaticString<nthChar(str, i)...>{};
[build]                             ^~~~~~~~~~~~~~~
[build] ../test.cpp:27:9: note: in instantiation of function template specialization 'makeStaticString<4, 0>' requested here
[build]         return makeStaticString(str, std::make_index_sequence<1>{}).data;
[build]                ^
[build] ../test.cpp:33:22: note: in instantiation of function template specialization 'buildStr<4>' requested here
[build]         constexpr auto ss = buildStr("123");
[build]                             ^
[build] ../test.cpp:21:30: note: function parameter 'str' with unknown value cannot be used in a constant expression
[build]         return StaticString<nthChar(str, i)...>{};
[build]                                     ^
[build] 1 error generated.

所以我的问题是,可以将模板参数包扩展为非类型模板参数,或者我犯了什么错误? 感谢您的帮助!

0 个答案:

没有答案