C++动态初始化const静态向量

3
我想在类 Foo 中初始化一个 static const std :: vector ,使其为 {0,1,2,3,...,n} ,其中n 是根据下面的 enum Last 中的 Last 值在编译时已知的。目标是让 Foo :: all 包含 Fruit 枚举的所有值。
foo.h 中:
enum Fruit { Apple, Orange, Banana, ..., Last };

class Foo {
public:
    static const vector<int> all;
};

foo.cpp中:
// initialization of Foo::all goes here.
3个回答

6
作为第三个选项:
namespace {
  std::vector<int> create();
}
const std::vector<int> Foo::all = create();

create()可以做任何它喜欢的事情,甚至对每个元素使用push_back(),因为它创建的vector不是const。

或者你可以使用<index_tuple.h>,使create()成为一个constexpr函数。

#include <redi/index_tuple.h>

namespace {
  template<unsigned... I>
    constexpr std::initializer_list<int>
    create(redi::index_tuple<I...>)
    {
      return { I... };
    }
}

const std::vector<int> Foo::all = create(typename redi::make_index_tuple<Last>::type());

4
你可以使用boost::irange:
auto range = boost::irange(0, n + 1);
const vector<int> Foo::numbers(range.begin(), range.end());

2
如果您的 n 很小,并且您使用支持 c++0xc++11 的编译器,那么就将其明确地写出来。
const std::vector<int> Foo::all{0, 1, 2, 3, ..., n};

根据@Jonathan的解释进行修正。


C++11的惯用方式不会使用=符号。 - Jonathan Wakely
@JonathanWakely,除了BigInt i = 5;BigInt i(5);这两种方式之外,还有什么区别吗?我从来没有听说过对此有强烈意见的人。 - chris
@JonathanWakely 好的,我不知道。g++接受任何一个。 - Olaf Dietsche
1
使用=符号等同于vector<int> v = vector<int>{0, 1, 2, 3, ..., n}。@chris的区别在于一个需要非显式构造函数和可访问的复制构造函数(显然,vector有,但并非所有类型都有)。例如,std::unique_ptr<int> p = new int;是无效的,但std::unique_ptr<int> p(new int);是有效的。 - Jonathan Wakely
@JonathanWakely,好的,我只是想知道在这种特定情况下是不是只有这个问题,还是还有其他问题。我知道直接初始化通常更可取 :) - chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接