RCPP - no matching function for call to 'transform' - c++

I have a problem while using Rcpp on Mac (on Windows the problem does not occur).
Here is the C++ Code that causes the error.
#include <Rcpp.h>
using namespace Rcpp;
NumericVector vecpow(const IntegerVector base, const NumericVector exp)
{
NumericVector out(base.size());
std::transform(base.begin(), base.end(), exp.begin(), out.begin(), ::pow);
return out;
}
Seems like nothing too fancy or complicated.
Still I get the following error when I try to compile it:
na_ma.cpp:7:3: error: no matching function for call to 'transform'
std::transform(base.begin(), base.end(), exp.begin(), out.begin(), ::pow);
^~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/algorithm:2028:1: note: candidate function template not viable: requires 4 arguments, but 5 were provided
transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
^
I am wondering how to fix this. While searching for solutions I came to some suggestions to create a Makevars file - but this did not work for me.
Would be also nice, if somebody could explain to me, why this error is occurring since I don't understand it.

This is actually C++ compiler error. Compiler cannot match ::pow with BinaryOp, so pack it into lambda. This works for me
std::transform(base.cbegin(), base.cend(), exp.cbegin(), out.begin(), [](double a, double b) {return ::pow(a, b); });
If lambdas are not available, one could try to make a functor (which lambda is equivalent to, please check https://medium.com/#winwardo/c-lambdas-arent-magic-part-1-b56df2d92ad2, https://medium.com/#winwardo/c-lambdas-arent-magic-part-2-ce0b48934809). Along the lines (untested code, I'm not at my computer)
struct pow_wrapper {
public: double operator()(double a, double b) {
return ::pow(a, b);
}
};
Then try
std::transform(base.cbegin(), base.cend(), exp.cbegin(), out.begin(), pow_wrapper());

Related

Standard overloaded std::abs doesn't match std::function<double (double)>

I'm getting the following error
min.cpp:17:30: error: no viable conversion from '<overloaded function type>' to 'Container::UnaryFun' (aka 'function<double (double)>')
this->addFunction("abs", abs);
when trying to compile the following code:
#include <cmath>
#include <string>
#include <functional>
class Test
{
public:
using UnaryFun = std::function<double (double)>;
Test()
{
this->addFunction("abs", abs);
}
auto addFunction(const std::string& name, UnaryFun fun) -> void
{
// ...
}
};
auto main() -> int {
Test eval;
return 0;
}
I've tried to check the declaration of std::abs for argument double and return type double and looks like this:
inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT {
return __builtin_fabs(__lcpp_x);
}
in /usr/local/Cellar/llvm/15.0.7_1/include/c++/v1/stdlib.h.
It is accesible specifically for the double type. I've checked this by adding:
double a = 5;
double b = std::abs(a);
and this compiles without problems or conversion warnings.
I've tried to declare my own abs function like so:
inline double xabs(double val)
{
return val < 0 ? -val : val;
}
and then change the following code like so to use this new xabs instead of std::abs
this->addFunction("abs", xabs);
and after this change, the code compiles.
Any ideas why the code with std::abs doesn't compile?
My environment:
OS: Mac OS 12.6
Compiler:
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Command to compile: g++ -std=c++2a -o min min.cpp
Update based on comments
I dug a bit deeper, and it seems that there is a problem with how std::function is declared, which led to the problem above.
If I declare addFunction like so, without std::function, the problem disappears.
auto addFunction(const std::string& name, double (*fun)(double)) -> void
{
}
This means that the compiler cannot figure out the matching abs if std::function is used but it can identify the matching overload if the type of the function is described directly without std::function.
The problem is that, since it has multiple overloads, std::abs doesn't have a single type. That means that the compiler can't select a std::function constructor to use to convert it since it can't deduce a type for the constructor's template parameter.
There are a couple of ways to get around that:
Use a cast:
addFunction("abs", std::static_cast<double(*)(double)>(std::abs));
Wrap it in a lambda:
addFunction("abs", [](double d) { return std::abs(d); });
As you've done, wrap it in a non-overloaded function

template operator visibility, gcc vs clang

I have this code, relying on a fold expression calling a very generic comparison operator:
#include <type_traits>
#include <vector>
#include <list>
template <typename Iter_a, typename Iter_b>
auto operator<(Iter_a, Iter_b) {
// original code makes more sense, I assure you
if constexpr ( std::is_same_v<Iter_a, Iter_b> ) {
return Iter_a();
}
else return Iter_b();
}
template <typename... Iterators>
using weakest_iterator = std::decay_t<decltype( (Iterators() < ...) )>;
int main() {
using lit = std::list<int>::iterator;
using vit = std::vector<int>::iterator;
using wi = weakest_iterator<lit, vit, float*>;
}
I have two problems with this code:
The first is that g++ compiles it and clang++ (-std=gnu++2a) refuses to do so:
prog.cc:14:64: error: call to function 'operator<' that is neither visible in the template definition nor found by argument-dependent lookup
using weakest_iterator = std::decay_t<decltype( (Iterators() < ...) )>;
^
prog.cc:19:16: note: in instantiation of template type alias 'weakest_iterator' requested here
using wi = weakest_iterator<lit, vit, float*>;
^
prog.cc:6:6: note: 'operator<' should be declared prior to the call site
auto operator<(Iter_a, Iter_b) {
Do you have any idea why? I find particularly troubling that clang requests a definition prior to the call site at line 19, that it finds by itself at line 6.
The second is that, if I modify it to invoke my meta-function with pointer template arguments (using wi = weakest_iterator<int*, float*, float*>;, I get another error message, this time only with g++ since clang refuses to compile, that I find difficult to really understand:
main.cpp: In substitution of 'template<class ... Iterators> using weakest_iterator = std::decay_t<decltype ((Iterators() < ...))> [with Iterators = {int*, float*, float*}]':
main.cpp:19:57: required from here
main.cpp:14:75: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
using weakest_iterator = std::decay_t<decltype( (Iterators() < ...) )>;
It seems that 1) the built-in overload of operator< is called (if there is anything such as this) over my ultra-generic one, and 2) that comparing an int* and a float* is considered the same as comparing a pointer and an integer.
Is it possible to make sure that my own implementation of operator< is chosen by the compiler?

Template function call ambiguity error

I am not familiar with templates. I've just started learning it. Why I am getting errors in following program?
#include <iostream>
#include <string>
using std::cout;
using std::string;
template<class C>
C min(C a,C b) {
return a<b?a:b;
}
int main()
{
string a="first string";
string b="second string";
cout<<"minimum string is: "<<min(a,b)<<'\n';
int c=3,d=5;
cout<<"minimum number is: "<<min(c,d)<<'\n';
double e{3.3},f{6.6};
cout<<"minimum number is: "<<min(e,f)<<'\n';
char g{'a'},h{'b'};
cout<<"minimum number is: "<<min(g,h)<<'\n';
return 0;
}
Errors:
13 [Error] call of overloaded 'min(std::string&, std::string&)' is ambiguous
6 [Note] C min(C, C) [with C = std::basic_string<char>]
Please help me.
There are a two things going on here.
Your first problem is that you only included part of the error message. Here is a link to the code being complied in gcc and clang, and one of the resulting error messages (in full):
main.cpp:13:34: error: call to 'min' is ambiguous
cout<<"minimum string is: "<<min(a,b)<<'\n';
^~~
/usr/include/c++/v1/algorithm:2579:1: note: candidate function [with _Tp = std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >]
min(const _Tp& __a, const _Tp& __b)
^
main.cpp:6:3: note: candidate function [with C = std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >]
C min(C a,C b) {
^
there are two candidates. One at main.cpp:6:3 (line 6, character 3) and one at algorithm:2579:1 (line 2579, character 1).
One of them you wrote, and one of them in #include <algorithm>.
One of your header files included <algorithm> without you asking for it. The standard headers are allowed to do this, as annoying as it is sometimes.
In <algorithm> there is a std::min function template. As std::string is an instance of a template class in namespace std, the function template std::min is found via a process called "argument dependent lookup" or "Koenig lookup". (function overload candidates are searched for locally, and also in the namespaces of the arguments to the function, and in the namespaces of the template arguments to the arguments to the function, and in the namespaces of the things pointed to by the arguments of the function, etc.)
Your local function min is also found, as it is in the same namespace as the body of main.
Both are equally good matches, and the compiler cannot decide which one you want to call. So it generates an error telling you this.
Both gcc and clang do error: then a sequence of note:s. Usually all of the note:s after an error are important to understanding the error.
To fix this, try calling ::min (fully qualifying the call), or renaming the function to something else, or make your version a better match than std::min (tricky, but doable in some cases), or calling (min)(a,b). The last blocks ADL/Koenig lookup, and also blocks macro expansion (for example, if some OS has injected #define min macros into their system headers) (via # 0x499602D2).
You're running into a name collision with std::min. It is likely included in one of the other standard libary headers that you included, either <iostream> or <string>, my guess is probably the latter. The quick fix is to rename your function. For example, renaming it to mymin works fine. Demo

error: template<class _Tp> std::complex<_Tp> std::polar(const _Tp&, const _Tp&

I am working on the eclipse (kepler) on C++11 and am required to use pow on a complex number (std::complex), but I get the following
error: template std::complex<_Tp> std::polar(const _Tp&, const _Tp&)
int Group::getActivity() const{
complex<int> c(this->getNum1(), this->getNum2());
c = pow(c, 3); //<--problem here
return abs(c);
}
the code itself doesn't have an error in this function but I get an overall error about it (this is the only use of complex in the entire code and I'm required to use it)
Just to be clear, I'm using std::complex and there is an include line at the beginning of the cpp file.
Does it work if you change int to double? The complex template is only meant to be used with floating point types (float, double, long double). I would suspect that this is the problem.
(This question has some authoritative links on the subject.)

Why does a global merge() function conflict with std::merge()?

Consider the following code:
#include <vector>
#include <algorithm>
template <typename Input1, typename Input2, typename Output>
void merge(Input1 begin1, Input1 end1, Input2 begin2, Input2 end2, Output out)
{
}
int main()
{
std::vector<int> a = {1, 2};
int b[] = {3, 4};
int c[4];
merge(a.begin(), a.end(), b, b + 2, c);
}
Compiling yields:
$ clang++ -std=c++11 -stdlib=libc++ merge.cpp
merge.cpp:15:5: error: call to 'merge' is ambiguous
merge(a.begin(), a.end(), b, b + 2, c);
^~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/algorithm:4056:1: note:
candidate function [with _InputIterator1 = std::__1::__wrap_iter<int *>,
_InputIterator2 = int *, _OutputIterator = int *]
merge(_InputIterator1 __first1, _InputIterator1 __last1,
^
merge.cpp:5:6: note: candidate function [with Input1 = std::__1::__wrap_iter<int
*>, Input2 = int *, Output = int *]
void merge(Input1 begin1, Input1 end1, Input2 begin2, Input2 end2, Output out)
^
1 error generated.
Compiler version:
$ clang++ --version
Apple LLVM version 5.0 (clang-500.2.78) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
Why is the call to merge ambiguous? It's not sure if I meant ::merge() or std::merge(), though clearly(?) it should be ::merge() since I'm not specifying any using directives. My merge function is in the global namespace, which I thought wouldn't conflict with anything in the std namespace (since that's the main point of namespaces, right?). If I change a to be an int array like the others, it compiles without any ambiguity. Also, adding the colons and calling ::merge() works fine.
So my question is this: Is this a bug in Clang, or do I have a misunderstanding of namespaces? Why does my call to merge() result in ambiguity when the two functions aren't in the same namespace and I haven't made std::merge() visible with any using directives?
The problem is that std::vector<T>::iterator may be a class type (in your case, it is a class type): during overload resolution the compiler finds all visible declarations of a function. To this end, it goes looking in namespaces possibly associated with its arguments (this is called argument dependent look-up). The type std::vector<T>::iterator is defined in namespace std (or a namespace nested within) and, thus, function from namespace std are considered for overload resolutions. Since std::merge() and your merge() both match equally well, there is an ambiguity.
The easiest way to avoid the problem is to use a different name for the function template. Hiding the associated namespace is possible but not easy: associated namespaces are taken from the location where a class or a class template is defined as well as from its base classes and template arguments. Thus, creating a wrapper template for any iterator type wouldn't be sufficient as it still associates the original namespace with the types. You may try to make your function template a better match but given that it is meant to be as generic as the standard algorithm, this isn't quite viable, either.
It's due to argument dependent look-up (http://en.cppreference.com/w/cpp/language/adl) of an iterator from the std namespace.
you could write ::merge to get your function only, but I'd rather just use a different name.