std::array<T, n> 如果T不是默认可构造的,我该如何初始化?
我知道可以像这样初始化它:
T t{args};
std::array<T, 5> a{t, t, t, t, t};
Run Code Online (Sandbox Code Playgroud)
但n对我来说是模板参数:
template<typename T, int N>
void f(T value)
{
std::array<T, N> items = ???
}
Run Code Online (Sandbox Code Playgroud)
即使它不是模板,如果n太大,手工重复值也很难看.
我需要std::array使用常量值初始化a的所有元素,就像可以使用来完成一样std::vector。
#include <vector>
#include <array>
int main()
{
std::vector<int> v(10, 7); // OK
std::array<int, 10> a(7); // does not compile, pretty frustrating
}
Run Code Online (Sandbox Code Playgroud)
有没有办法优雅地做到这一点?
现在我正在使用这个:
std::array<int, 10> a;
for (auto & v : a)
v = 7;
Run Code Online (Sandbox Code Playgroud)
但我想避免使用显式代码进行初始化。
我最近开始使用C++ 14而不是C++ 11来使我的C++代码库现代化.
在用C++ 14 替换了一次std::unique_ptr.reset(new ...)使用后std::make_unique,我意识到我的测试套件(由大约30个C++测试程序组成)运行速度慢了约50%.
旧C++ 11代码(快速):
class Foo
{
public:
Foo(size_t size)
{
array.reset(new char[size]);
}
private:
std::unique_ptr<char[]> array;
};
Run Code Online (Sandbox Code Playgroud)
新的C++ 14代码(慢):
class Foo
{
public:
Foo(size_t size)
{
array = std::make_unique<char[]>(size);
}
private:
std::unique_ptr<char[]> array;
};
Run Code Online (Sandbox Code Playgroud)
使用C++ 14代码时,GCC和Clang都运行得慢得多std::make_unique.当我使用valgrind测试两个版本时,它报告C++ 11和C++ 14代码使用相同数量的分配和相同数量的已分配内存,并且没有内存泄漏.
当我查看上面生成的测试程序的程序集时,我怀疑C++ 14版本std::make_unique在使用memset分配后使用重置内存.C++ 11版本没有这样做:
C++ 11程序集(GCC 7.4,x64)
main:
sub rsp, 8
movsx rdi, edi
call operator new[](unsigned long)
mov rdi, rax
call operator delete[](void*)
xor eax, eax
add rsp, …Run Code Online (Sandbox Code Playgroud) 我正在尝试初始化一个设置为-1的int数组.
我尝试了以下,但它不起作用.它只将第一个值设置为-1.
int directory[100] = {-1};
Run Code Online (Sandbox Code Playgroud)
为什么它不能正常工作?
以下代码有效,但我想避免警告:
警告:'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;
}
Run Code Online (Sandbox Code Playgroud)
我应该忽略这个警告吗?有没有办法填写vect_构造函数初始化列表(不更改其类型)?
我想初始化一个模板大小的对象数组,没有默认的构造函数,如下面的代码所示:
#include <array>
template<std::size_t N>
class Foo
{
public:
class Bar
{
Foo<N> & _super;
public:
Bar(Foo<N> *super) :
_super(*super)
{
}
};
std::array<Bar, N> _array;
Foo(void) :
_array{{}} // We need {this, ...} N times
{
}
};
int main(void)
{
Foo<3> foo;
(void)foo;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是一种说法:"我想要一个N个对象的数组,所有对象都使用相同的参数进行初始化"?我认为模板元编程有一种方法,但我无法想象如何做到这一点.
我有一个简单的例子,我创建了std::array一些Foo元素:
struct Foo
{
Foo(int bar=0) : m_bar(bar)
{
// Code depending on the value of bar
}
int m_bar;
};
const unsigned int num = // get array size
std::array<Foo, num> fooArr;
Run Code Online (Sandbox Code Playgroud)
当我在构造函数中使用初始化列表时,m_bar(bar)它将所有设置Foo.m_bar为0(因为这是默认的构造函数参数值).如果我不这样做,那么垃圾值就满了.
我的问题是如何在不知道数据大小之前将另一个与默认值不同的值传递给数组中每个元素的构造函数?
我在创建数组时尝试使用init列表,如下所示:std::array<Foo, 5> fooArr{3}但是只将第一个元素设置m_bar为3.
我有一个类定义为
class Edgelet
{
private:
const int e_size;
//Other private members...
public:
//The constructor
explicit Edgelet (int size, Color cl1 = Color::NA, Color cl2 = Color::NA);
//Other public members...
Run Code Online (Sandbox Code Playgroud)
由于类中有一个const成员,因此编译器隐式删除了默认的复制构造函数。需要给它一个参数来初始化。
问题出在课堂上
class Cube
{
private:
std::array <Edgelet, 12> c_edgelets;
//Other members...
public:
//The constructor
Cube(int size)
//Other public members...
Run Code Online (Sandbox Code Playgroud)
此类包含先前类对象的std::array。我如何初始化这个数组?所述尺寸参数需要被提供给的每个元素的std ::阵列初始化。我想将std::array 的每个元素设置为Edgelet(size - 2).
当然,我可以使用初始化列表,但由于构造函数有 12 个元素和其他参数,而不是显示,代码变得很难看。此外,我用 6 个元素而不是 12 个元素进行了类似的处理。
我还尝试为参数提供默认值,但由于有一个const成员,因此以后无法更改该值。我也尝试查看std::initializer_list但似乎您无法向其中添加新元素(或者您可以??)。有没有一种有效的方法来做到这一点?
假设我有一个没有名为 的默认构造函数的类Foo。
如果我使用std::vector,我可以这样做:
std::vector<Foo> vec(100, Foo(5));
Run Code Online (Sandbox Code Playgroud)
这将创建一个包含 100 个元素的向量,每个元素都有值Foo(5)。
我该如何做同样的事std::array<Foo, 100>?
我显然不想Foo(5)在初始化列表中显式列出 100 次。但我不能等到数组构造完成后才对其进行初始化,因为缺少默认构造函数将产生编译器错误。
通过提供类似于“placement new”或函数的显式构造函数参数,该解决方案还允许我避免复制构造函数emplace。