[英]How do I return by value for an “auto” return type function
Ok I don't know if I explained that very well with the title, so I'll just give an example. 好的,我不知道我对标题的解释是否很好,所以我只举一个例子。 I'm trying to come up with a function that finds the median of a series of floating point numbers (and a little bit extra).
我试图提出一个函数,该函数可以找到一系列浮点数的中位数(还有一些额外的值)。 Here is the function:
这是函数:
//get the median of an unordered set of numbers of arbitrary type without modifying the
//underlying dataset
template <typename InputIterator>
auto Median(
InputIterator const cbegin,
InputIterator const cend,
bool const abs = false // get the median of the absolute values rather than nominal values
) -> decltype(*cbegin)
{
typedef std::iterator_traits<InputIterator>::value_type T;
std::vector<T> data;
data.reserve(std::distance(cbegin, cend));
// get a copy of the values for sorting
for (InputIterator it = cbegin; it != cend; ++it)
{
if (abs)
data.push_back(std::abs(*it));
else
data.push_back(*it);
}
// find the median
std::nth_element(data.begin(), data.begin() + data.size() / 2, data.end());
return data[data.size() / 2];
}
Here is the output if I try to compile this: 如果我尝试编译此,则为以下输出:
warning C4172: returning address of local variable or temporary
警告C4172:返回局部变量或临时地址
I have tried replacing decltype(*cbegin)
with std::remove_reference<decltype(*cbegin)>::type
or std::iterator_traits<decltype(*cbegin)>::value_type
but those don't compile either. 我试图替换
decltype(*cbegin)
与std::remove_reference<decltype(*cbegin)>::type
或std::iterator_traits<decltype(*cbegin)>::value_type
但那些不进行编译任一。
Is there a simple solution to this? 有一个简单的解决方案吗? How do I return the type to which
InputIterator
points? 如何返回
InputIterator
指向的类型?
EDIT: Here is a fixed version based on feedback: 编辑:这是基于反馈的固定版本:
//get the median of an unordered set of numbers of arbitrary type without modifying the
//underlying dataset
template <typename RandomAccessIterator>
typename std::iterator_traits<RandomAccessIterator>::value_type Median(
RandomAccessIterator const cbegin,
RandomAccessIterator const cend,
bool const abs = false // get the median of the absolute values rather than nominal values
)
{
typedef std::iterator_traits<RandomAccessIterator>::value_type T;
std::vector<T> data(cbegin, cend);
// find the median
std::nth_element(data.begin(), data.begin() + data.size() / 2, data.end(),
[abs](T const a, T const b)
{
return abs ? std::abs(b) > std::abs(a) : b > a;
});
return data[data.size() / 2];
}
You can use iterator_traits
with template parameter, no decltype needed: 您可以将
iterator_traits
与模板参数一起使用,而无需decltype:
template <typename InputIterator>
typename std::iterator_traits<InputIterator>::value_type
Median(
InputIterator const cbegin,
InputIterator const cend,
bool const abs = false
);
Note the typename
keyword - it's what was missing in your attempts. 请注意
typename
关键字-这是您尝试中缺少的内容。
The compiler is telling you that you are returning something temporary and, actually, you are. 编译器告诉您,您实际上正在返回一些临时信息。
The decltype(*cbegin) is a reference (so you can write code like *it = 12
), so you are returning a reference to some value inside data
which is temporary. decltype(* cbegin)是一个引用(因此您可以编写
*it = 12
类的代码),因此您将返回对data
内部临时值的引用。
You can remove the reference by using std::remove_reference<decltype(*cbegin)>::type
您可以使用
std::remove_reference<decltype(*cbegin)>::type
删除引用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.