说我有3个变量:
vector<int> vec(3);
int stat[3];
auto dyn = make_unique<int[]>(3);
如果我知道尺寸为3,我可以初始化其中任何一个:
for(auto i = 0; i < 3; ++i) X[3] = i;
X
的位置,vec
,stat
或dyn
。但我希望能够通过再次传递X
来在模板中执行此操作。我需要做的是:
我能在以下函数中得到它吗?
template <typename T>
void init(T& X);
或者我无法从unique_ptr
中提取尺寸信息?或者以通用的方式输入? (我已经将这个问题标记为C ++ 17,希望可以使用size
。)
答案 0 :(得分:2)
您无法从唯一指针获取大小。当您使用auto dyn = make_unique<int[]>(3);
时,它会被翻译为
make_unique<int[]>(new int[3]())
这是一个指针,我们丢失了大小信息。对于唯一指针,所有数组重载都会将销毁中的delete
调用更改为delete[]
。如果你想使用unique_ptr
“数组”那么你将需要传递大小。
答案 1 :(得分:2)
你不能为unique_ptr<T[]>
执行此操作 - 这仍然只是一个原始指针,不知道它的大小是什么。
但是任何其他容器,你甚至不需要size()
。只需C ++ 11即可:
template <class T>
void init(T& container) {
for (auto& elem : container) {
elem = 3;
}
}
您可以在其上添加SFINAE或static_assert
,以确保T
的元素实际上可分配给3
,但这样就足够了。
答案 2 :(得分:1)
如果您使用相应内容的循环,那么您实际上并不关心实际的容器或持有者。这是使用一对迭代器,数组视图或范围的好时机。 E.g:
template<typename It>
void init(It first, It last)
{
// or use an algorithm, e.g. std::iota(first, last, 0)
int i = 0;
for(; first != last; ++last, ++i) *first = i;
}
// use as:
using std::begin;
using std::end;
init(begin(vec), end(vec));
init(begin(stat), end(stat));
init(dyn.get(), dyn.get() + 3);
请注意,您必须在std::unique_ptr<int[]>
案例中对大小3进行硬编码,或者在变量中的某处自己跟踪它。否则无法提供尺寸信息。