编译时文字字符串作为模板参数

Ric*_*ade 5 string-literals template-meta-programming variadic-templates constexpr c++11

我正在尝试将C++文字字符串转换为以下模板的实例:

template <char ... C>
struct string_literal {
    typedef string_constant type;
    static constexpr const char value[sizeof...(C)] = {C...};
    constexpr operator const char* (void) const {
        return value;
    }
};
template <char ... C>
constexpr const char string_literal<C...>::value[sizeof...(C)];
Run Code Online (Sandbox Code Playgroud)

我想出了基于各种来源的这些帮助器,用于将引用的字符串值"解包"到上面的模板中.

template <unsigned N, const char (&S) [N], typename U>
struct selector;

template <unsigned N, const char (&S) [N], unsigned ...I>
struct selector<N, S, index_sequence<I...>> {
    using type = string_literal<S[I]...>;
};

template <unsigned N, const char (&S) [N]>
struct unpack {
    using type = typename selector<N, S, make_index_sequence<N>>::type;
};
Run Code Online (Sandbox Code Playgroud)

但是,当一个调用这个我得到一个编译器错误:

template <unsigned N>
constexpr auto make_string_literal(const char (&s) [N]) {
    return unpack<N, s>{}; // Error here
}

constexpr auto literal = make_string_literal("test");
// string_literal<'t','e','s','t','\0'>
Run Code Online (Sandbox Code Playgroud)

GCC 4.9+报告: 错误:'const char(&s)[1]'不是类型'const char(&)[1]'的有效模板参数,因为引用变量没有常量地址

Clang 3.7.1报告: 错误:非类型模板参数指的是没有链接的对象''

我尝试了一些不同的方法,但错误大致相同.我在这里错过了什么?

pre*_*eys 2

这是满足您需求的令人满意的解决方案吗?

template <char ... C>
struct string_literal {
    static constexpr const char value[sizeof...(C)] = {C...};
    constexpr operator const char* (void) const {
        return value;
    }
    void foo() {std::cout << value << '\n';}
};
template <char ... C> constexpr const char string_literal<C...>::value[sizeof...(C)];

template <typename CharT, CharT... Cs>
constexpr string_literal<Cs...> operator ""_create() {
    return {};
}

int main() {
    string_literal<'t','e','s','t'> s = "test"_create;
    std::cout << s << '\n';  // test
    s.foo();  // test
}
Run Code Online (Sandbox Code Playgroud)

  • 根据其他人的评论,这取决于 GNU 扩展(constexpr 用户定义的文字),它既不是当前或下一个 C++ 标准的一部分(到目前为止):http://cplusplus.github.io/EWG/ewg -active.html#66 (2认同)