C++ 在编译时前置到静态字符串

C++ 在编译时前置到静态字符串,c++,c++17,C++,C++17,扩展数组引用时遇到问题。当我将数组引用作为参数传递给函数模板时,数组引用的常量性质似乎丢失了: #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_

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

#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);
}
#包括
#包括
模板
结构提示\u用于\u opt\u cls\u持有者{
constexpr静态const char值[]{'?',C..};
};
模板
静态constexpr自动
为选项cls创建提示(常量字符(&cname)[N],
std::索引(U序列){
//失败:cname不是常量表达式
返回提示\u,用于\u opt\u cls\u holder::value;
}
模板
静态constexpr自动
为选项cls创建提示(const char(&cname)[N]){
constexpr decltype(auto)cname_=cname;//实际上这里已经失败了
返回创建选项cls的提示(cname,
std::make_index_sequence());
}
constexpr静态字符名[]=“foobar”;
constexpr静态自动获取类名称(){
返回名称;
}
int main(){
//工作!知道回报是恒定的
constexpr decltype(auto)cname=get_class_name();
自动x=为选择cls(cname)创建提示;
}

参数不是
constexpr
,您必须将其转换为以下类型:

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

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

你只需要
constexpr
就可以得到表达式。对于像
“foobar”
这样的东西,你可以只
常量…
。谢谢你的回答。以下几点:1)在另一个答案中,您有这样的定义:
模板constepr char at(const char(&a)[N]){return I
。为什么这会起作用,而不是我的
为\u opt\u cls创建\u提示\u
?2) 这是数组引用的特殊之处吗?如果我传递的是
std::array
,这会有什么不同吗?您不能在函数本身中使用参数作为constexpr,但constexpr结果可能取决于输入。数组引用、
std::array
或任何文字类型都没有什么特别之处。
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;