我有一个函数接受 double*
void funct(double*);
我有一个 vector :
std::vector<double> myVec;
我应该如何正确安全地调用 funct(myVec)?
不安全:
funct(&myVec[0]);
funct(&*myVec.begin());
不好读:
funct( myVec.empty()? NULL : &myVec[0]);
funct( myVec.empty()? NULL : &*myVec.begin());
有什么建议吗?
标准方法是什么?
最佳答案
嗯,标准类类型 std::vector
有一个名为 data
的成员函数,它应该返回指向底层存储的指针。 Apparently data()
只不过是 &front()
保证:
The pointer is such that range
[data(); data() + size())
is always a valid range, even if the container is empty.
因此我会说两者:
funct(vector.data());
funct(&vector.front());
可以安全使用。
但真正的问题是:你想在函数内部做什么?
我可以看到 3 个明显的答案,我将为所有人提出替代方案:
- 我只想要数组中的一个元素
- 我想要一个可选参数
- 我要传递一个容器
让我们从第一个开始,好吗?如果你只想要数组的一个元素,为什么还要费心于指针和数组呢?你可以只使用:
void funct(double);
并完成它。如果您想修改那个 double
,为什么不通过引用传递它呢?
void funct(double&);
并将函数调用为:
funct(vector[0]);
第二个有两个非常可能的答案。一种是像这样使用函数重载:
void funct();
void funct(double);
并且基本上考虑无参数和有参数的函数。最简单的解决方案可能是正确的,对吗?
否则,如果您真的很喜欢并且懒得写两次 funct
,您甚至可以使用 boost::optional
或 std::optional
(C++14),它清楚地表达了参数的意图:
void funct(std::optional<double> optional) {
if (optional) {
// we have a double
} else {
// we don't have a double
}
}
最后,第三个有三个可能的答案(你能看出规律吗?)。
如果你只想要一种特定类型的容器(你为什么想要那个,只有上帝知道)你可以简单地做:
void funct(const std::vector<double>&);
否则你可以使用像Bartek explained below这样的模板或者使用我最喜欢的解决方案:迭代器(这也是标准算法的选择,只是为了让它不那么正式)。
你猜怎么着?它也适用于 C 风格的数组(顺便说一句,你不应该使用它)。这是解决方案:
template<class Iterator>
void funct(Iterator begin, Iterator end) {
for (auto it = begin; it != end; ++it) {
// do something to element (*it)
}
}
然后繁荣。你可以像这样使用它:
double x[100];
funct(std::begin(x), std::end(x));
或:
std::vector<double> x(100);
funct(x.begin(), x.end());
快乐编码。
关于c++ - 将指针传递给 vector 的第一个元素(如果有),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21556305/