所以,我正试图像人们将要做的那样弄乱 constexpr
字符串,到目前为止实际上只有这个:
template<char... CS> struct text {
static constexpr char c_str[] = {CS...};
static constexpr int size = sizeof...(CS);
};
这样编译
text<'a','b','c'> t;
std::cout<< t.c_str <<std::endl;
并按预期输出 'abc'
。
我想知道是否有一种简单的方法可以进行相反的操作;有一个函数,在给定 char
数组的情况下返回具有必要的 char
模板参数的文本类型。
最佳答案
不完全是你问的......而且有点令人费解,我想......但是如果你定义一个 constexpr
函数来检测字符串的长度
constexpr std::size_t strLen (char const * str, std::size_t len = 0U)
{ return *str ? strLen(++str, ++len) : len; }
和定义所需类型的辅助结构
template <char const *, typename>
struct foo_helper;
template <char const * Str, std::size_t ... Is>
struct foo_helper<Str, std::index_sequence<Is...>>
{ using type = text<Str[Is]...>; };
你可以通过字符串获取你的类型
template <char const * Str>
struct foo : public foo_helper<Str, std::make_index_sequence<strLen(Str)>>
{ };
不幸的是,您不能以这种方式将字符串文字传递给它
foo<"abc">::type
但是你必须从一个全局变量传递
constexpr char abcVar[] = "abc";
并使用全局变量调用foo
foo<abcVar>::type
此解决方案使用 std::index_sequence
和 std::make_index_sequence
,仅从 C++14 开始可用,但编写替代品并不难他们在 C++11 中。
下面是一个完整的工作示例
#include <utility>
#include <iostream>
#include <type_traits>
template <char ... CS>
struct text
{
static constexpr char c_str[] = {CS...};
static constexpr int size = sizeof...(CS);
};
constexpr std::size_t strLen (char const * str, std::size_t len = 0U)
{ return *str ? strLen(++str, ++len) : len; }
template <char const *, typename>
struct foo_helper;
template <char const * Str, std::size_t ... Is>
struct foo_helper<Str, std::index_sequence<Is...>>
{ using type = text<Str[Is]...>; };
template <char const * Str>
struct foo : public foo_helper<Str, std::make_index_sequence<strLen(Str)>>
{ };
constexpr char abcVar[] = "abc";
int main()
{
static_assert(std::is_same<foo<abcVar>::type,
text<'a', 'b', 'c'>>{}, "!");
}
题外话:我建议在c_str[]
中添加一个结尾的零
static constexpr char c_str[] = {CS..., 0};
如果您想将它用作std::string
的c_str()
方法。
关于c++ - 一种从元组/数组获取参数包的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49389411/