在成员初始化列表中填写std :: array

时间:2014-02-24 16:47:44

标签: c++ c++11 stdarray effective-c++

以下代码有效,但我想避免警告:

  

警告:' fitness :: vect _'应该在初始化   成员初始化列表[-Weffc ++]

使用g++ -Weffc++开关编译时:

#include <array>

template<class T, unsigned N>
class fitness
{
public:
  explicit fitness(T v)
  {
    static_assert(N, "fitness zero length");

    vect_.fill(v);
  }

private:
  std::array<T, N> vect_;
};

int main()
{
  fitness<double, 4> f(-1000.0);

  return 0;
}

我应该忽略警告吗?有没有办法在构造函数初始化列表中填充vect_(不更改其类型)?

5 个答案:

答案 0 :(得分:4)

我相信你可以忽略这个警告。

如果在构造函数中为数组放置一个空的初始化,它就可以工作:

#include <array>

template<class T, unsigned N>
class fitness
{
public:
  explicit fitness(T v):
  vect_{}
  {
    static_assert(N, "fitness zero length");

    vect_.fill(v);
  }

private:
  std::array<T, N> vect_;
};

int main()
{
  fitness<double, 4> f(-1000.0);

  return 0;
}

答案 1 :(得分:2)

尝试使用

explicit fitness(T v) : vect_{}
{
//...
}

答案 2 :(得分:2)

在这种情况下,默认构造函数(read:value initializer)应该可以正常工作。由于std::array是聚合类型,因此每个元素都将进行值初始化,对于像double这样的数字类型,这意味着零初始化,然后您可以使用fill

explicit fitness(T v) : vect_() // or vect_{}
{
    vect_.fill(v);
}

如果您不想基本上将初始化加倍,那么使用std::vector及其填充构造函数可能会更好。然后你的班级将成为:

template<class T>
class fitness
{
public:
  explicit fitness(T v, unsigned n) : vect_(n, v)

private:
  std::vector<T> vect_;
};

int main()
{
   fitness<double> f(-1000.0, 4);

   return 0;
}

当然,您仍然可以将N作为模板参数,但不需要这样做,因为在编译时不需要知道长度。 (另一方面,如果坚持使用std::array,您可以将构造函数设置为constexpr,但这可能需要一些模板摆弄或辅助constexpr函数返回一个初始化列表工作正常,我还没有充分利用C ++ 11概念来了解。)

答案 3 :(得分:1)

生成filled_array的函数应该省略其返回值:

template<unsigned N, typename T>
std::array<T, N> filled_array_sized( T const& t ) {
  std::array<T, N> retval;
  retval.fill( t );
  return retval;
}

但是,如果不是类型N,则需要传递至少T的尺寸。

template<typename T>
struct array_filler {
  T && t;
  template<typename U, unsigned N>
  operator std::array<U, N>()&& {
    return filled_array_sized<N, U>( std::forward<T>(t) );
  }
  array_filler( T&& in ):t(std::forward<T>(in)) {}
};
template<typename T>
array_filler< T >
filled_array( T&& t ) {
  return array_filler<T>( t );
}

请注意,不建议将filled_array的返回值存储在auto中。

使用:

#include <array>

template<class T, unsigned N>
class fitness
{
public:
  explicit fitness(T v): vect_( filled_array( std::move(v) ) ) {
    //...
  }
//...

我不知道上面的代码是否会在filled_array_size的实现中生成警告,但如果是,则在本地禁用警告。

答案 4 :(得分:1)

这是另一种方式,更清洁的恕我直言,使用C++11 non-static data member initializers

#include <array>

template<class T, unsigned N>
class fitness
{
public:
  explicit fitness(T v)
  {
    static_assert(N, "fitness zero length");

    vect_.fill(v);
  }

private:
  std::array<T, N> vect_ { };
};

int main()
{
  fitness<double, 4> f(-1000.0);

  return 0;
}