从元组/数组获取参数包的方法?

时间:2018-03-20 16:23:53

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

所以,我试图弄乱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模板参数。

1 个答案:

答案 0 :(得分:2)

不完全是你提出的问题...而且有点复杂,我想......但是如果你定义一个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_sequencestd::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};

如果您想将其用作c_str()的{​​{1}}方法。