[英]How can I use unique pointers for an array of parameterized objects in C++ using Visual Studio 2017?
Consider a class whose default constructor takes in the file path as a parameter.考虑一个类,其默认构造函数将文件路径作为参数。
class Test
{
public:
Test(const std::string& filepath);
...
...
};
Now I wish to create and initialize an array of Test
objects using unique pointers in VS2017.现在我希望在 VS2017 中使用唯一指针创建和初始化一组
Test
对象。
int main()
{
std::unique_ptr<Test[]> m_Tests;
int testCount = 2;
std::string path1, path2;
m_Tests = std::make_unique<Test[]>(testCount); // This line gives a compilation error
m_Tests[0] = std::make_unique<Test>(path1);
m_Tests[1] = std::make_unique<Test>(path2);
}
How can I make this work?我怎样才能使这项工作?
g++ 9.2.0 tells me that you lack default constructor, ie one without parameters. g++ 9.2.0 告诉我您缺少默认构造函数,即没有参数的构造函数。 Adding such constructor works fine.
添加这样的构造函数工作正常。 If it's not what you want, you can create array of unique_ptr's, so
std::unique_ptr<std::unique_ptr<Test>[]>
and after that initialize each element by hand, something similar to this:如果这不是你想要的,你可以创建 unique_ptr 的数组,所以
std::unique_ptr<std::unique_ptr<Test>[]>
然后手动初始化每个元素,类似于:
#include <memory>
#include <algorithm>
#include <iostream>
struct Test {
std::string str_;
Test(std::string const& str) : str_(str) { }
void print() { std::cout << str_ << '\n'; }
};
int main()
{
std::unique_ptr<std::unique_ptr<Test>[]> m_Tests;
int testCount = 2;
std::string path1{"a"}, path2{"b"};
m_Tests = std::make_unique<std::unique_ptr<Test>[]>(testCount);
std::array<std::string, 2> paths{path1, path2};
std::transform(paths.begin(), paths.end(), &m_Tests[0],
[](auto const& p) { return std::make_unique<Test>(p); });
for (int i = 0 ; i < testCount ; ++i) {
m_Tests[i]->print();
}
}
There is no overload of std::make_unique
that does this, so you would need to use new
directly:执行此操作的
std::make_unique
没有重载,因此您需要直接使用new
:
m_Tests.reset(new Test[testCount]{path1, path2});
This will however only compile if testCount
is a constant expression, so you need to change the definition int testCount = 2;
然而,这只会在
testCount
是一个常量表达式时才编译,因此您需要更改定义int testCount = 2;
to const int
or constexpr int
.到
const int
或constexpr int
。
If testCount
is not a constant expression, there needs to be a default constructor defined for the case that testCount
is smaller than 2
at runtime.如果
testCount
不是常量表达式,则需要为testCount
在运行时小于2
的情况定义一个默认构造函数。
So, really, you probably want to ignore testCount
and just let the array size be deduced:因此,实际上,您可能想忽略
testCount
并仅推导出数组大小:
m_Tests.reset(new Test[]{path1, path2});
It would be much easier if you just used std::vector
:如果您只使用
std::vector
会容易得多:
std::vector<Test> m_Tests;
//...
m_Tests.emplace_back(path1);
m_Tests.emplace_back(path2);
How about you use std::array and can you get rid of testCount (or use it as constexp) then the code can be like below.您如何使用 std::array 并且您可以摆脱 testCount (或将其用作 constexp )然后代码可以如下所示。
class Test
{
public:
Test(const std::string& filepath){}
};
int main()
{
constexpr int testCount = 2;
std::unique_ptr<std::array<Test, testCount>> m_Tests;
std::string path1, path2;
m_Tests = std::make_unique<std::array<Test, testCount>>(std::array<Test, testCount>{path1,path2});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.