我正在阅读 C++ Templates: The complete guide本书的第 4 章(4.2 非类型函数模板参数)是一个模板函数的示例,它可以与 STL 容器一起使用,为集合的每个元素添加值。这是完整的程序:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
template<typename T, int VAL>
T addValue(T const& x)
{
return x + VAL;
}
int main()
{
std::vector<int> source;
std::vector<int> dest;
source.push_back(1);
source.push_back(2);
source.push_back(3);
source.push_back(4);
source.push_back(5);
std::transform(source.begin(), source.end(), dest.begin(), (int(*)(int const&)) addValue<int, 5>);
std::copy(dest.begin(), dest.end(), std::ostream_iterator<int>(std::cout, ", "));
return 0;
}
我不得不做出那个丑陋的 Actor 阵容,因为书上说:
Note that there is a problem with this example: addValue<int,5> is a function template, and function templates are considered to name a set of overloaded functions (even if the set has only one member). However, according to the current standard, sets of overloaded functions cannot be used for template parameter deduction. Thus, you have to cast to the exact type of the function template argument:
std::transform (source.begin(), source.end(), // start and end of source
dest.begin(), // start of destination
(int(*)(int const&)) addValue<int,5>); // operation
我的问题是运行程序时出现段错误。我正在 Mac 上使用 Clang 构建它。
是 Actor 阵容不正确还是还有其他问题?
最佳答案
强制转换不是您的问题,您正在将元素输出到空的 vector
。相反,您可以调整
您需要的空间大小:
dest.resize(source.size());
或者更好的是让transform
来解决这个问题:
std::transform(
source.begin(), source.end()
, std::back_inserter( dest ) // needs <iterator>
, &addValue<int, 5> // cast should not be needed
);
尽管如果您确实知道它将占用多少空间,调整大小
vector 将具有更好的性能,因为它将避免添加项目时的内部重新分配。另一种选择是调用 reserve
以避免内部重新分配:
dest.reserve(source.size());
// dest is still empty
std::transform(
source.begin(), source.end()
, std::back_inserter( dest ) // needs <iterator>
, &addValue<int, 5> // cast should not be needed
);
关于c++ - 为集合的每个元素添加值的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14094764/