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

时间:2016-02-27 06:38:17

标签: c++11 variadic-templates template-meta-programming constexpr string-literals

我正在尝试将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)];

我根据各种来源找到了这些助手,将引用的字符串值“解压缩”到上面的模板中。

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;
};

然而,当调用这个时我得到编译器错误:

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'>

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

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

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

1 个答案:

答案 0 :(得分:1)

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

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
}