簡體   English   中英

C ++ 11:使用另一個constexpr char數組初始化constexpr char數組

[英]C++11: Initialize constexpr char array with another constexpr char array

我想初始化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;
}

我想初始化constexpr char[]與其他部件constexpr char []構件。 是否可以在C++11或更高版本中完成?

從C ++ 14開始,您可以使用std::make_index_sequencestd::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_sequencestd::index_sequence

在此特定示例中,您可以將Value聲明為以下內容:

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

請注意,除非您切換到-std = c ++ 17或在源文件中添加以下行,否則GCC將無法鏈接此示例。

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{}) {}
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM