首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >initializer_list先验C++11的替代方案

initializer_list先验C++11的替代方案
EN

Stack Overflow用户
提问于 2016-06-14 16:07:43
回答 3查看 451关注 0票数 2

我有很多这样的代码

代码语言:javascript
复制
MyClass v = {1,2,3,4,5,6};

不幸的是,我的项目是一个愚蠢的ARM编译器,它不支持花哨的C++11特性,特别是它不支持'initialyzer_list‘。目前唯一的解决方案如下所示:

代码语言:javascript
复制
MyClass v(6);
v[0]=1;
v[1]=2;
...

像上面这样的代码和手工编辑的问题是灾难性的。有什么办法用更少的血来克服它吗?宏,库,很好的技巧,还有什么可以用MyClass中的代码进行查找-替换-regexp的吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-14 18:05:26

如果可以在前面将列表声明为一行数组,则可以将大小作为模板参数:

代码语言:javascript
复制
class MyClass {
  public:
    template <std::size_t N>
    MyClass(const int (&in)[N]);
};

int main() {
    static const int arr[] = {1,2,3,4,5,6};
    MyClass mc(arr);
}
票数 3
EN

Stack Overflow用户

发布于 2016-06-14 17:55:31

代码语言:javascript
复制
template<class T>
struct span {
  T* b;
  T* e;
  span( T* s, T* f ):b(s), e(f) {}

  T* begin() const { return b; }
  T* end() const { return e; }
  std::size_t size() const { return end()-begin(); }
};

template<class T, std::size_t N>
struct chain_array {
  T arr[N];

  T const& operator[](std::size_t i) const {return arr[i];}
  std::size_t size() const { return N; }
  T const* begin() const { return arr; }
  T const* end() const { return arr+N; }

  operator span<T>() const {
    return span<T>(begin(), end());
  }

  chain_array<T, N+1> operator,( T rhs ) {
    chain_array<T, N+1> r;
    for (std::size_t i=0; i < N; ++i)
      r[i]=(*this)[i];
    r[N] = rhs;
    return r;
  }
};

template<class T>
chain_array<T, 1> chain( T t ) {
  chain_array<T, 1> r;
  r[0] = t;
  return r;
}

现在写这个:

代码语言:javascript
复制
MyClass v = (chain(1),2,3,4,5,6);

并添加过载的MyClass::MyClass(span<T>)

这个解决方案效率低下,因为我创建了中间数组,它们直到行尾才会被丢弃。聪明的编译器可以解决这个问题。

我们可以创建一个指针或引用链(基本上是一个表达式模板),如果我们愿意的话,只有当我们转换成最终的il<T>类型时,我们才会崩溃。

票数 2
EN

Stack Overflow用户

发布于 2016-06-14 18:52:19

作为瑞安海宁上面的解决方案的一个小小的替代方案,您实际上不需要将数组放在前面一行的变量中:

代码语言:javascript
复制
#include <iostream>

struct A {
  template<size_t N>
  A(const int (&list)[N]) {
    size = N;
    myArr = new int[N];
    int *tmp = myArr;
    for(const int *i = list; i < list + N; ++i) {
      *tmp++ = *i;
    }
  }

  ~A() {
    delete[] myArr;
  }

  int *myArr;
  size_t size;
};

int main(int argc, char **argv) {
  A a = (int[]) {1, 2, 3, 4, 5};
  for(int i = 0; i < a.size; ++i) {
    std::cout << a.myArr[i] << std::endl;
  }
  return 0;
}

由于复制省略和隐式构造函数,您可以只在同一行上进行强制转换。数组被隐式转换为您的类型,然后通过复制省略有效地将temp值移到堆栈动态存储中。这意味着修改代码只需要几个(type[]),并且重构构造函数要基于数组而不是基于initializer_list。不幸的是,如果没有c++11 foreach循环,这可能有点烦人,但是如果使用一些指针工作,这并不可怕,而且您总是可以做一些方便的宏,例如:

代码语言:javascript
复制
#define FOREACH(type, name, arr, N)\
  for(type *__foreach__ptr__ = arr, (name) = *__foreach__ptr__;\
  __foreach__ptr__ < (arr) + (N);\
  ++__foreach__ptr__, (name) = *__foreach__ptr__)

可用于如下用途:

代码语言:javascript
复制
int N = 5;
int arr[N] = {1, 2, 3, 4, 5};
FOREACH(int, val, arr, N) {
  std::cout << val << std::endl;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37817106

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档