C++11:用另一个 constexpr char 数组初始化 constexpr char 数组

问题描述 投票:0回答:2

我想用另一个

constexpr char[]
成员初始化
constexpr char []
成员。可以做
C++11
或以上吗?

#include <iostream>

struct Base {
 static constexpr char ValueOne[] = "One";
 static constexpr char ValueTwo[] = "Two";
};

template <typename T>
struct ValueOneHolder {
  static constexpr char Value[] = T::ValueOne; // << How can one initialize this?
};

int main() {
  std::cout << ValueOneHolder<Base>::Value << std::endl;
  return 0;
}
c++ arrays c++11 template-meta-programming constexpr
2个回答
2
投票

在此特定示例中,您可以将 Value 声明如下:

template <typename T>
struct ValueOneHolder {
  static constexpr auto Value = T::ValueOne; // << How can one initialize this?
};

请注意,GCC 将无法链接此示例,除非您切换到 -std=c++17 或在源文件中添加以下行。

constexpr char Base::ValueOne[];
constexpr char Base::ValueTwo[];

使用 C++14,还可以制作 constexpr 字符串(或其子字符串)的 constexpr 副本,如下面的示例所示:

template<typename CharT, size_t Size>
struct basic_cestring {
    using value_type = CharT;
    template<size_t... I> constexpr
    basic_cestring(const char* str, index_sequence<I...>)
      : _data{str[I]...} {}
    inline constexpr operator const CharT* () const { return _data; }
    const CharT _data[Size + 1];
};

template<size_t Size>
struct cestring : public basic_cestring<char, Size>  {
    using index = make_index_sequence<Size>;
    constexpr cestring(const char* str)
    : basic_cestring<char, Size>(str, index{}) {}
};

2
投票

我想用另一个

constexpr char[]
成员初始化
constexpr char []
成员。可以做
C++11
或以上吗?

从 C++14 开始,您可以使用

std::make_index_sequence
std::index_sequence

如果您适合从事

ValueOneHolder
专业工作,您首先可以开发一个
constexpr
函数,给定 C 风格数组,返回数组的大小

template <typename T, std::size_t N>
constexpr std::size_t getDim (T const (&)[N])
 { return N; }

Nest,您可以声明

ValueOneHolder
添加第二个模板参数,其默认值是与
T::ValueOne

对应的索引序列
template <typename T,
          typename = std::make_index_sequence<getDim(T::ValueOne)>>
struct ValueOneHolder;

最后是简单的部分:带有初始化的部分特化

template <typename T, std::size_t ... Is>
struct ValueOneHolder<T, std::index_sequence<Is...>>
 { static constexpr char Value[] = { T::ValueOne[Is] ... }; };

不要忘记结构体之外的以下行

template <typename T, std::size_t ... Is>
constexpr char ValueOneHolder<T, std::index_sequence<Is...>>::Value[];

以下是完整的C++14编译示例

#include <utility>
#include <iostream>

struct Base
 {
   static constexpr char ValueOne[] = "One";
   static constexpr char ValueTwo[] = "Two";
 };

template <typename T, std::size_t N>
constexpr std::size_t getDim (T const (&)[N])
 { return N; }

template <typename T,
          typename = std::make_index_sequence<getDim(T::ValueOne)>>
struct ValueOneHolder;

template <typename T, std::size_t ... Is>
struct ValueOneHolder<T, std::index_sequence<Is...>>
 { static constexpr char Value[] = { T::ValueOne[Is] ... }; };

template <typename T, std::size_t ... Is>
constexpr char ValueOneHolder<T, std::index_sequence<Is...>>::Value[];

int main()
 {
   std::cout << ValueOneHolder<Base>::Value << std::endl;
 }

如果您想要 C++11,您可以开发

std::make_index_sequence
std::index_sequence
的替代品。

© www.soinside.com 2019 - 2024. All rights reserved.