I am in the process of finishing a package I've been working on. All checks look good and it compiles without problems on my computer. win-builder
has no problems with the package as well. As further check, I've tried to install from source on the computer of a colleague and it fails. The problem comes from a Rcpp function that I've taken from a StackOverflow thread on vector powers in Rcpp:
NumericVector vecpow(const NumericVector base, const NumericVector exp) {
NumericVector out(base.size());
std::transform(base.begin(), base.end(),
exp.begin(), out.begin(), ::pow);
return out;
}
This compiles and works fine for me, but throws an error for my colleague when installing, involving
error: no matching function function for call to 'transform'
and
candidate function template not viable: requires 4 arguments, but 5 were provided.
I can reproduce the error for instance by replacing ::pow
in the original code by pow
. I'm on Windows 8.1, my colleague is on Mac. The colleague maintains his own packages involving extensive amounts of Rcpp code and usually has no problems with compiling.
I assume that this might be a compiler problem. The original thread has some alternative code involving C++11 (thread is already five years old), so in principle, I could replace the problematic code using alternatives. However, as I'm not very experienced with this, this would be trial and error. My question is: Is there a simple reason why this error pops up? And how can I modify my code in order to be sure that the package will be installable and usable for most users?
the error is caused because the compiler can't match the std::pow
function as binary operation (this may be due to the fact that it has at least two overloads and the compiler can't guess the types float/double) giving rise to the following note :
note: candidate template ignored: couldn't infer template argument '_BinaryOperation'
And then it falls back to the unary std::transform
which only has 4 arguments pushing the second note:
note: candidate function template not viable: requires 4 arguments, but 5 were provided
Compilation stops as it hasn't found a valid std::transform
to apply to the specified arguments.
Switching from pow
to powf
stops this issue as the compiler doesn't have to resolve any overloads, however precision might be lost due to this change :
Rcpp::cppFunction("NumericVector vecpow(const NumericVector base, const NumericVector exp) {
NumericVector out(base.size());
std::transform(base.begin(), base.end(),
exp.begin(), out.begin(), ::powf);
return out;
}
") -> pow
pow(1:5,5:1)
[1] 1 16 27 16 5
Another work around would be to use static cast i.e replace ::pow
with static_cast<double(*)(double, double)>(::pow)
to tell the compiler to use the double
overload of pow