如何在 C++ 仿函数中传递 lambda 函数?
How to pass lambda function in a c++ functor?
我是 Rccp 和 Rccpparallel 的新手,我很难弄清楚我在哪里犯了错误。所以我想创建一个函数,在矩阵中并行执行幂元素。我正在关注 rcppParallel 示例。
在一个核心上,代码编译并运行良好,但是当我尝试将 n 传递给下面的仿函数时,出现以下错误。
capture of non-variable "Power::n"
"this" was not captured for this lambda function
invalid use of non-static data member "Power::n"
如果我在下面的仿函数中交换 n,它会编译并且工作正常。我错过了什么?
R代码:
library(Rcpp)
library(RcppParallel)
Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
sourceCpp("lambdaPower.cpp")
lambdaPower.cpp
#include <Rcpp.h>
using namespace Rcpp;
#include <cmath>
#include <algorithm>
// [[Rcpp::export]]
NumericMatrix matrixPower(NumericMatrix orig, double n)
{
// allocate the matrix we will return
NumericMatrix mat(orig.nrow(), orig.ncol());
// transform it
std::transform(orig.begin(), orig.end(), mat.begin(), [n](double x) { return pow(x, n); });
// return the new matrix
return mat;
}
// [[Rcpp::depends(RcppParallel)]]
#include <RcppParallel.h>
using namespace RcppParallel;
struct Power : public Worker
{
// source matrix
const RMatrix<double> input;
// destination matrix
RMatrix<double> output;
//power
double n;
// initialize with source and destination
Power(const NumericMatrix input, NumericMatrix output, double n)
: input(input), output(output), n(n){}
// take the n power of the range of elements requested
void operator()(std::size_t begin, std::size_t end)
{
std::transform(input.begin() + begin,
input.begin() + end,
output.begin() + begin,
[n](double x) { return pow(x,n); }); // why n doesn work?
// If i swap n with fixed number it compiles and works.
// [](double x) { return pow(x,2); }); compiles and works
}
};
// [[Rcpp::export]]
NumericMatrix parallelMatrixPower(NumericMatrix x, double n)
{
// allocate the output matrix
NumericMatrix output(x.nrow(), x.ncol());
// power functor (pass input and output matrixes)
Power power(x, output, n);
// call parallelFor to do the work
parallelFor(0, x.length(), power);
// return the output matrix
return output;
}
非常感谢。
如果您将 n
复制到定义 lambda 的范围内,您的代码将编译:
....
void operator()(std::size_t begin, std::size_t end)
{
auto _n = n;
std::transform(input.begin() + begin,
input.begin() + end,
output.begin() + begin,
[_n](double x) { return pow(x,_n); });
}
....
我不太擅长解释这一点,但您可以阅读 Scott Meyers 的 "Effective Modern C++" 的 "Item 31: Avoid default capture modes" 中的详细信息。
顺便说一句,我会在 C++ 代码中使用 // [[Rcpp::plugins(cpp11)]]
而不是 R 代码中的 Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
。
我是 Rccp 和 Rccpparallel 的新手,我很难弄清楚我在哪里犯了错误。所以我想创建一个函数,在矩阵中并行执行幂元素。我正在关注 rcppParallel 示例。
在一个核心上,代码编译并运行良好,但是当我尝试将 n 传递给下面的仿函数时,出现以下错误。
capture of non-variable "Power::n"
"this" was not captured for this lambda function
invalid use of non-static data member "Power::n"
如果我在下面的仿函数中交换 n,它会编译并且工作正常。我错过了什么? R代码:
library(Rcpp)
library(RcppParallel)
Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
sourceCpp("lambdaPower.cpp")
lambdaPower.cpp
#include <Rcpp.h>
using namespace Rcpp;
#include <cmath>
#include <algorithm>
// [[Rcpp::export]]
NumericMatrix matrixPower(NumericMatrix orig, double n)
{
// allocate the matrix we will return
NumericMatrix mat(orig.nrow(), orig.ncol());
// transform it
std::transform(orig.begin(), orig.end(), mat.begin(), [n](double x) { return pow(x, n); });
// return the new matrix
return mat;
}
// [[Rcpp::depends(RcppParallel)]]
#include <RcppParallel.h>
using namespace RcppParallel;
struct Power : public Worker
{
// source matrix
const RMatrix<double> input;
// destination matrix
RMatrix<double> output;
//power
double n;
// initialize with source and destination
Power(const NumericMatrix input, NumericMatrix output, double n)
: input(input), output(output), n(n){}
// take the n power of the range of elements requested
void operator()(std::size_t begin, std::size_t end)
{
std::transform(input.begin() + begin,
input.begin() + end,
output.begin() + begin,
[n](double x) { return pow(x,n); }); // why n doesn work?
// If i swap n with fixed number it compiles and works.
// [](double x) { return pow(x,2); }); compiles and works
}
};
// [[Rcpp::export]]
NumericMatrix parallelMatrixPower(NumericMatrix x, double n)
{
// allocate the output matrix
NumericMatrix output(x.nrow(), x.ncol());
// power functor (pass input and output matrixes)
Power power(x, output, n);
// call parallelFor to do the work
parallelFor(0, x.length(), power);
// return the output matrix
return output;
}
非常感谢。
如果您将 n
复制到定义 lambda 的范围内,您的代码将编译:
....
void operator()(std::size_t begin, std::size_t end)
{
auto _n = n;
std::transform(input.begin() + begin,
input.begin() + end,
output.begin() + begin,
[_n](double x) { return pow(x,_n); });
}
....
我不太擅长解释这一点,但您可以阅读 Scott Meyers 的 "Effective Modern C++" 的 "Item 31: Avoid default capture modes" 中的详细信息。
顺便说一句,我会在 C++ 代码中使用 // [[Rcpp::plugins(cpp11)]]
而不是 R 代码中的 Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
。