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

问题描述 投票:1回答:1

我正在尝试在我的班级static constexpr std::vector中初始化std::stringFoo。我稍后会使用其元素的地址。

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,谢谢。

c++ c++11 static initialization constexpr
1个回答
2
投票

我可以和const一起使用而不是constexpr。但是有点奇怪,没有办法做到这一点

你可以和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的大小是max-length加1(加上最后的零)。

现在您可以按如下方式定义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;
 }
© www.soinside.com 2019 - 2024. All rights reserved.