【问题标题】:Prepend to static string at compile time在编译时添加到静态字符串
【发布时间】:2020-11-21 03:02:25
【问题描述】:

我在扩展数组引用时遇到问题。当我将数组引用作为参数传递给函数模板时,数组引用的常量性质似乎丢失了:

#include <cstdlib>
#include <utility>

template<const char ... C>
struct hint_for_opt_cls_holder {
    constexpr static const char value[] { '?', C... };
};
template<size_t N, size_t... Is>
static constexpr auto
create_hint_for_opt_cls(const char (&cname)[N],
                        std::index_sequence<Is...>) {
    // fails: cname is not a constant expression
    return hint_for_opt_cls_holder<cname[Is]...>::value;
}
template<size_t N>
static constexpr auto
create_hint_for_opt_cls(const char (&cname)[N]) {
    constexpr decltype(auto) cname_ = cname; // fails already here, actually
    return create_hint_for_opt_cls(cname,
                                    std::make_index_sequence<N>());
}

constexpr static char name[] = "foobar";
constexpr static auto& get_class_name() {
    return name;
}
int main() {
    // works! knows the return is constant
    constexpr decltype(auto) cname = get_class_name();
    auto x = create_hint_for_opt_cls(cname);
}

【问题讨论】:

  • 您只需要constexpr 来处理表达式。对于"foobar" 之类的内容,您只需const ...

标签: c++ c++17


【解决方案1】:

参数不是constexpr,你必须把它们转入type:

gcc/clang 有一个扩展允许从文字字符串构建 UDL:

// That template uses the extension
template<typename Char, Char... Cs>
constexpr auto operator"" _cs() -> std::integer_sequence<Char, Cs...> {
    return {};
}

如果您不能使用扩展名,请参阅String-interning at compiletime for profiling 我的回答以使用 MAKE_STRING 宏(对于接受的字符串长度确实更冗长且硬编码限制)。

然后

template<char ... Cs>
static constexpr auto
create_hint_for_opt_cls(std::integer_sequence<char, Cs...>) {
    return hint_for_opt_cls_holder<Cs...>::value;
}

constexpr static auto name = "foobar"_cs;

【讨论】:

  • 感谢您的回答。几个跟进:1)在你的其他答案中,你有这个定义:template &lt;std::size_t I, std::size_t N&gt; constexpr char at(const char (&amp;a)[N]) { return I &lt; N ? a[I] : '\0'; }。为什么这行得通,但我的create_hint_for_opt_cls 不行? 2)这是数组引用的特别之处吗?如果我通过std::array&lt;char, N&gt; 会有什么不同吗?
  • 您不能在函数内部使用参数作为 constexpr,但 constexpr 结果可能取决于输入。数组引用、std::array 或任何文字类型没有什么特别之处。
猜你喜欢
  • 2016-12-21
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
相关资源
最近更新 更多