11

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

警告:“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_构造函数初始化列表(不改变其类型)?

4

5 回答 5

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;
}
于 2014-02-24T16:56:07.550 回答
2

尝试使用

explicit fitness(T v) : vect_{}
{
//...
}
于 2014-02-24T16:56:34.277 回答
2

在这种情况下,默认构造函数(读取:值初始化程序)应该可以正常工作。作为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你也许可以将构造函数设置为 a constexpr,尽管这可能需要一些模板摆弄或返回初始化列表的辅助constexpr函数才能正常工作,但我还没有玩够要知道的 C++11 概念。)

于 2014-02-24T16:57:48.893 回答
1

生成 a 的函数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在 an中。auto

利用:

#include <array>

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

不知道上面的代码在执行中会不会产生警告filled_array_size,如果有,就在本地禁用警告。

于 2014-02-24T18:31:02.890 回答
1

这是另一种方式,更干净的恕我直言,使用C++11 非静态数据成员初始化程序

#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;
}
于 2014-02-24T21:19:57.160 回答