Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将`hana::string`转换为`constexpr const char(&;)[]`_C++_String_C++14_Constexpr_Boost Hana - Fatal编程技术网

C++ 将`hana::string`转换为`constexpr const char(&;)[]`

C++ 将`hana::string`转换为`constexpr const char(&;)[]`,c++,string,c++14,constexpr,boost-hana,C++,String,C++14,Constexpr,Boost Hana,我有一些旧代码,它使用了一些与所描述的str_const非常相似的东西,并执行一些constepr字符串操作str_const是Scott Schurr描述的一种文本类型,可以从字符串文本构造,因为它有一个来自const char(&)[]的模板构造函数 我现在还使用了一些新代码boost::hana 我希望能够获取一个hana::string并创建一个引用它的str_const。最简单的方法是将hana::string转换为constepr const char(&)[]。(实际上,在这一点上

我有一些旧代码,它使用了一些与所描述的
str_const
非常相似的东西,并执行一些constepr字符串操作
str_const
是Scott Schurr描述的一种文本类型,可以从字符串文本构造,因为它有一个来自
const char(&)[]
的模板构造函数

我现在还使用了一些新代码
boost::hana

我希望能够获取一个
hana::string
并创建一个引用它的
str_const
。最简单的方法是将
hana::string
转换为
constepr const char(&)[]
。(实际上,在这一点上,这不是最简单的方法,最简单的方法肯定是在我的
str_const
实现中添加一个新的模板构造函数。但在这一点上,这个问题本身就存在,我主要感兴趣的是,是否可以用
hana::string
来完成。因此,假设我不允许这样做更改
str_const
实现。)

但是,在
hana
中,将
hana::string
转换为运行时字符串的方法是
hana::to

乐观地说,我尝试了各种形式的
hana::to(…)
,但这会导致
hana
中的静态断言失败

hana
docs建议的另一个选项是使用
hana::unpack
,然后将字符粘贴到数组中。我写了这段代码

template <typename T, size_t N>
struct array {
  T arr[N];
};

struct char_packer {
  template <typename... Ts>
  constexpr auto operator()(Ts... ts) -> array<const char, sizeof...(ts) + 1> {
    return array<const char, sizeof...(ts) + 1>{{ ts... , 0 }};
  }
};

template <typename S>
struct string_keeper {
  static constexpr auto my_array = hana::unpack(S{}, char_packer{});
};

template <int N>
using char_arr = const char [N];

template <typename S>
constexpr auto to_string_literal(S &&) -> const char_arr<decltype(hana::length(S{}))::value + 1> & {
  return string_keeper<S>::my_array.arr;
}
模板
结构数组{
T arr[N];
};
结构字符包装器{
模板
constexpr自动运算符()(Ts…Ts)->数组{
返回数组{ts..,0};
}
};
模板
结构字符串{
静态constexpr auto my_array=hana::unpack(S{},char_packer{});
};
模板
使用char_arr=const char[N];
模板
constexpr auto to_string_literal(S&&)->const char_arr&{
返回字符串\u keeper::my\u array.arr;
}
我认为这几乎是可行的,至少它可以编译。但是,如果在运行时也使用了引用,那么它将失败,并出现链接器错误:
未定义对。。。字符串:我的数组

(事实上,我想我理解为什么这是一个ODR问题,如果我再思考一段时间,我可能会记得如何修复它…不确定…)

凭直觉,我觉得一定有办法做到这一点。因为,
hana
已经允许我将
hana::string
转换为
constexpr const char*
,指针正好指向我想要的数组。事实上,它甚至暗示可能存在一个邪恶的选项,我试图强制
const char*
返回
(&)[]
类型,尽管这似乎也需要执行
constepr
函数中不允许的操作。不管怎样,如果hana能制作出那个数组,那么我当然也能,或者以某种方式说服它更准确地把它给我


有没有办法修复我上面的代码?在我忽略的
hana中,有没有更简单的方法来实现这一点?由于某种原因,这实际上是不可能的吗?

另一个问题是,当从函数返回时,原始字符数组将衰减为指针。我建议在函数的上下文中构造
str_const
对象,我相信该对象满足了创建
str_const
的意图,而无需更改其接口

下面的示例使用顶级变量模板来创建数组,而
hana::string
实现使用该数组:

#define BOOST_HANA_CONFIG_ENABLE_STRING_UDL
#include <boost/hana.hpp>
#include <stdexcept>

namespace hana = boost::hana;
using namespace hana::literals;

class str_const {
    const char * const p_;
    const std::size_t sz_;
public:
    template <std::size_t N>
    constexpr str_const( const char( & a )[ N ] )
    : p_( a ), sz_( N - 1 ) {}
    constexpr char operator[]( std::size_t n ) const {
        return n < sz_ ? p_[ n ] : throw std::out_of_range( "" );
    }
    constexpr std::size_t size() const { return sz_; }
};

template <char ...c>
constexpr char string_storage[sizeof...(c) + 1] = {c..., '\0'};

struct to_str_const_helper {
  template <typename ...Ts>
  constexpr auto operator()(Ts...) {
    return str_const(string_storage<Ts::value...>);
  }
};
template <typename S>
constexpr auto to_str_const(S) {
  return hana::unpack(S{}, to_str_const_helper{});
}

int main()
{
  constexpr str_const str = to_str_const("foo"_s);
  static_assert(str[0] == 'f', "");
  static_assert(str[1] == 'o', "");
  static_assert(str[2] == 'o', "");
}
\define BOOST\u HANA\u CONFIG\u ENABLE\u STRING\u UDL
#包括
#包括
名称空间hana=boost::hana;
使用名称空间hana::文本;
类str_const{
常量字符*常量p_;
const std::size_t sz;
公众:
模板
constexpr str_const(const char(&a)[N])
:p_(a),sz_(N-1){}
constexpr字符运算符[](std::size\u t n)const{
返回n
这个答案启发我将hana元组转换为T(&)[N]之类的函数。太神了