获取 return 类型的 lambda 表达式
Get return type of lambda expression
我正在开发一个 C++ 迭代器,每次取消引用迭代器时都会计算 lambda 表达式。
所以我实现了一个自定义迭代器 class,并且我重载了取消引用运算符,以某种方式它在每次取消引用时执行 lambda 表达式,这样我就可以将我需要的表达式放在 lambda 函数中。
一切正常,但它不是泛型的,因为在下面代码的第 9 行,我假设 lambda 表达式 return 是一个双精度值。如何获得 Lambda 的 return 类型?我尝试了 std::result_of<Lambda>
,但没有成功。
这是我写的代码:
#include <iostream>
#include <vector>
#include <utility>
#include <cmath>
template <class Iterator, class Lambda>
struct LambdaIterator: Iterator {
public:
using value_type = double; // <--- How do I get the return type of the lambda?
LambdaIterator(Iterator&& begin, Lambda&& lambda) :
Iterator(std::forward<Iterator>(begin)),
lamdaexpr(std::forward<Lambda>(lambda)) {}
value_type operator*() {
return lamdaexpr(*static_cast<Iterator&>(*this));
}
private:
Lambda lamdaexpr;
};
// Helper function, only needed to easily instantiate the iterator
template <class Iterator, class Lambda>
LambdaIterator<Iterator, Lambda> MakeLambdaIterator(Iterator&& begin, Lambda&& lambda) {
return {std::forward<Iterator>(begin), std::forward<Lambda>(lambda)};
}
template<class BeginIterator, class EndIterator>
typename BeginIterator::value_type Sum(BeginIterator begin, EndIterator end) {
typename BeginIterator::value_type sum = 0;
while (begin != end) {
sum += *begin;
begin++;
}
return sum;
}
int main() {
std::vector<double> vec;
for (int i = 0; i < 10; i++)
vec.push_back(i); // Puts some data into the vector
std::cout << Sum(vec.begin(), vec.end()) << std::endl; // Works fine
std::cout << Sum(MakeLambdaIterator(vec.begin(),
[](double item) -> double { // Works as long as it returns a double
return sqrt(item); // Prints the sum of the square roots
} ), vec.end()) << std::endl;
std::cout << Sum(MakeLambdaIterator(vec.begin(),
[](double item) -> double {
return pow(item, 2); // Prints the sum of the squares
} ), vec.end()) << std::endl;
}
有几种方法可以实现它,最简单的似乎如下:
decltype(auto) operator*() {
return lamdaexpr(*static_cast<Iterator&>(*this));
}
How do I get the return type of the Lambda?
考虑到您知道参数的类型,在我看来您是在 decltype()
.
中寻找执行
我的意思是
using value_type = decltype( std::declval<Lambda>()(*std::declval<Iterator>()) );
这也适用于通用 lambda。
题外话:如果你想为 LambdaIterator()
构造函数使用前向语义,你必须在模板中将其转换为将 &&
作为通用引用而不是右值引用。
我的意思是:你应该这样写
template <typename I, typename L>
LambdaIterator (I && begin, L && lambda)
: Iterator{std::forward<I>(begin)}, lamdaexpr{std::forward<L>(lambda)}
{ }
我正在开发一个 C++ 迭代器,每次取消引用迭代器时都会计算 lambda 表达式。
所以我实现了一个自定义迭代器 class,并且我重载了取消引用运算符,以某种方式它在每次取消引用时执行 lambda 表达式,这样我就可以将我需要的表达式放在 lambda 函数中。
一切正常,但它不是泛型的,因为在下面代码的第 9 行,我假设 lambda 表达式 return 是一个双精度值。如何获得 Lambda 的 return 类型?我尝试了 std::result_of<Lambda>
,但没有成功。
这是我写的代码:
#include <iostream>
#include <vector>
#include <utility>
#include <cmath>
template <class Iterator, class Lambda>
struct LambdaIterator: Iterator {
public:
using value_type = double; // <--- How do I get the return type of the lambda?
LambdaIterator(Iterator&& begin, Lambda&& lambda) :
Iterator(std::forward<Iterator>(begin)),
lamdaexpr(std::forward<Lambda>(lambda)) {}
value_type operator*() {
return lamdaexpr(*static_cast<Iterator&>(*this));
}
private:
Lambda lamdaexpr;
};
// Helper function, only needed to easily instantiate the iterator
template <class Iterator, class Lambda>
LambdaIterator<Iterator, Lambda> MakeLambdaIterator(Iterator&& begin, Lambda&& lambda) {
return {std::forward<Iterator>(begin), std::forward<Lambda>(lambda)};
}
template<class BeginIterator, class EndIterator>
typename BeginIterator::value_type Sum(BeginIterator begin, EndIterator end) {
typename BeginIterator::value_type sum = 0;
while (begin != end) {
sum += *begin;
begin++;
}
return sum;
}
int main() {
std::vector<double> vec;
for (int i = 0; i < 10; i++)
vec.push_back(i); // Puts some data into the vector
std::cout << Sum(vec.begin(), vec.end()) << std::endl; // Works fine
std::cout << Sum(MakeLambdaIterator(vec.begin(),
[](double item) -> double { // Works as long as it returns a double
return sqrt(item); // Prints the sum of the square roots
} ), vec.end()) << std::endl;
std::cout << Sum(MakeLambdaIterator(vec.begin(),
[](double item) -> double {
return pow(item, 2); // Prints the sum of the squares
} ), vec.end()) << std::endl;
}
有几种方法可以实现它,最简单的似乎如下:
decltype(auto) operator*() {
return lamdaexpr(*static_cast<Iterator&>(*this));
}
How do I get the return type of the Lambda?
考虑到您知道参数的类型,在我看来您是在 decltype()
.
我的意思是
using value_type = decltype( std::declval<Lambda>()(*std::declval<Iterator>()) );
这也适用于通用 lambda。
题外话:如果你想为 LambdaIterator()
构造函数使用前向语义,你必须在模板中将其转换为将 &&
作为通用引用而不是右值引用。
我的意思是:你应该这样写
template <typename I, typename L>
LambdaIterator (I && begin, L && lambda)
: Iterator{std::forward<I>(begin)}, lamdaexpr{std::forward<L>(lambda)}
{ }