以下代码有效,但我想避免警告:
警告:' 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_
(不更改其类型)?
答案 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;
}