c++ - 如何在 C++11 中初始化 std::vector<std::string> 的静态 constexpr 成员?

标签 c++ c++11 static initialization constexpr

我正在尝试在我的类 Foo 中初始化 std::stringstatic constexpr std::vector。稍后我将使用其元素的地址。

class Foo {
public:
  static constexpr std::vector<std::string> a = {"a", "bc", "232"}; // not working, constexpr variable not literal ....
  const std::vector<std::string> a = {"a", "bc", "232"}; // this works
}

使用 c++11,谢谢。

最佳答案

I can live with const instead of constexpr. but it's a little bit odd that there's no way to do this

很高兴你能忍受const但是,为了好玩,我向您展示了一种创造胜于无的方法 constexpr static使用 std::array 的成员而不是 std::vector和(再次)std::array而不是 std::string .

很遗憾,您使用的是 C++11,所以没有 std::index_sequence/std::make_index_sequence (从 C++14 开始可用)但我在以下完整示例中添加了 C++11 替代品。

如果您知道要在 constexpr 中使用的字符串长度的上限成员,比如说 9(在你的例子中是 3),你可以定义一个 fakeString输入如下

using fakeString = std::array<char, 10u>;

观察 std::array 的大小是最大长度加一(加上最后的零)。

现在你可以定义foo如下

struct foo
 {
   static constexpr std::array<fakeString, 3u> a
    {{ fs("a"), fs("bc"), fs("232") }};
 };

constexpr std::array<fakeString, 3u> foo::a;

哪里fs()constexpr返回 fakeString 的函数给定一个 C 风格数组 char并使用 fsh()辅助函数

fs()fsh()功能如下

template <std::size_t ... Is, std::size_t N>
constexpr fakeString fsh (indexSequence<Is...> const &, char const (&s)[N])
 { return {{ s[Is]... }}; }

template <std::size_t N>
constexpr fakeString fs (char const (&s)[N])
 { return fsh(makeIndexSequence<N>{}, s); }

现在您可以使用 foo::a如下

   for ( auto const & fakeS : foo::a )
      std::cout << fakeS.data() << std::endl;

请注意,您必须调用 data()返回 char * 的方法, 那是一个 C 风格的字符串。

我重复一遍:只是为了好玩。

下面是一个完整的编译C++11的例子

#include <array>
#include <iostream>

template <std::size_t...>
struct indexSequence
 { using type = indexSequence; };

template <typename, typename>
struct concatSequences;

template <std::size_t... S1, std::size_t... S2>
struct concatSequences<indexSequence<S1...>, indexSequence<S2...>>
   : public indexSequence<S1..., ( sizeof...(S1) + S2 )...>
 { };

template <std::size_t N>
struct makeIndexSequenceH
   : public concatSequences<
               typename makeIndexSequenceH<(N>>1)>::type,
               typename makeIndexSequenceH<N-(N>>1)>::type>::type
 { };

template<>
struct makeIndexSequenceH<0> : public indexSequence<>
 { };

template<>
struct makeIndexSequenceH<1> : public indexSequence<0>
 { };

template <std::size_t N>
using makeIndexSequence = typename makeIndexSequenceH<N>::type;

using fakeString = std::array<char, 10u>;

template <std::size_t ... Is, std::size_t N>
constexpr fakeString fsh (indexSequence<Is...> const &, char const (&s)[N])
 { return {{ s[Is]... }}; }

template <std::size_t N>
constexpr fakeString fs (char const (&s)[N])
 { return fsh(makeIndexSequence<N>{}, s); }

struct foo
 {
   static constexpr std::array<fakeString, 3u> a
    {{ fs("a"), fs("bc"), fs("232") }};
 };

constexpr std::array<fakeString, 3u> foo::a;

int main ()
 {
   for ( auto const & fakeS : foo::a )
      std::cout << fakeS.data() << std::endl;
 }

关于c++ - 如何在 C++11 中初始化 std::vector<std::string> 的静态 constexpr 成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52264304/

相关文章:

c++ - 基本构造函数根据输入调用派生的构造函数-在运行时选择对象子类型

c++ - vector push_back() 给出编译器错误 C2280

java - 为什么类中的静态方法在其对象为空时不会给出空指针异常

c++ - 动态声明数组背后的静态声明

c++ - 如何在 C++ 中获取使用 system() 命令执行的进程的 pid

c++ - 你什么时候在 C++ 中使用 ZeroMemory 结构?

C++11 兼容的线性分配器实现

java - 这两种初始化静态变量的方式有什么区别?

c++ - 在 OSX 上将我的代码与 ARPACK 链接时出现问题(将 MacPorts 用于 ARPACK)

c++ PRINT macro linux - 添加日期和时间