So I'm trying to deal with a program that can accept a function that either returns a vector of doubles, or just returns a single double.
Unfortunately, when I try to compile this (MSVC2010) I get the following error:
ambiguous call to overloaded function
Is there anything I'm doing that's obviously wrong? I need a way to differentiate between the two, and I'm trying to avoid hackish template metaprogramming.
#include <iostream>
#include <functional>
#include <vector>
std::vector<double> foo(std::function<std::vector<double>(unsigned int) > a){return a(10);}
double foo(std::function<double(unsigned int) > a){return a(11);}
int main(){
foo([](unsigned int)->double{return 12.0;});
return 0;
}
As you can see, my return type is explicitly declared to be a double, yet it can't decide which version of foo to call.
Should I just run back to function pointers?
Thank you very much for your time!
Related
The following code
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>, boost::multiprecision::et_off> float_50;
int main()
{
float_50 a = boost::multiprecision::pow((float_50)5, (float_50)10); // works
double b = boost::multiprecision::pow((double)5, (double)10); // doesn't work
//double b = boost::multiprecision::pow<double>((double)5, (double)10); // Why can't be overloaded?
return 0;
}
won't compile since boost::multiprecision::pow does not recognised fixed precision type. What is the usual solution for this? I'd rather have a single pow function which accepts both multi and fixed precision types. It is strange to me that boost constants, for instance, have template definitions so
boost::math::constants::pi<double>()
boost::math::constants::pi<float_50>()
work fine. Shouldn't boost::multiprecision::pow also be overloaded?
The solution is to leave off the namespace.
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>, boost::multiprecision::et_off> float_50;
int main()
{
float_50 a = pow((float_50)5, (float_50)10);
double b = pow(5., 10.);
return 0;
}
There is no way for a single function to handle arguments of different types. You need a separate function for each supported parameter set. The function may be autogenerated from a template—but pow does not seem to be a candidate for a template implementation.
I did exactly what was written here: Easiest way to convert int to string in C++
But I get an error at the std of std::to_string
#include <iostream>
#include <string>
int main()
{
std::string s = std::to_string(42);
return 0;
}
The error message you get can't be generated for a standard-conforming library implementation.
So, the best solution is to upgrade the compiler (presumably it's some years old Visual C++).
An alternative is to use an argument of type long, and hope that that's one of the existing overloads:
std::to_string( 42L )
I want to copy all the integers contained in a into b.
#include <vector>
#include <iterator>
#include <boost/bind.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/range/algorithm/copy.hpp>
void test()
{
std::vector<std::vector<int> > a;
std::vector<int> b;
boost::for_each(a, boost::bind(boost::copy, _1, std::back_inserter(b)));
}
It looks so simple. I'd like to have a C++ 98 compatible one liner.
Why doesn't this compile?
I have a long list of error regarding boost::bind, which I don't understand, moreover, it is multiple pages long.
The error starts with :
error C2780: 'boost::_bi::bind_t<_bi::dm_result::type,boost::_mfi::dm,_bi::list_av_1::type> boost::bind(M T::* ,A1)' : expects 2 arguments - 3 provided
There is a directly related question here: Can I use (boost) bind with a function template?. The error message in that question is identical, and the problem differs in that their template function is not a library one.
The trick here is that you are intending to bind a template function boost::copy<>(), which, according to the linked question, isn't possible because the template function must be instantiated in order to be passed as a function pointer. This is also indicated here, section "Binding a template function". So, unfortunately, you need to resort to a rather long construct, which can be slightly shortened with the use of typedef (since you're in C++98, no decltype is available either):
int main()
{
typedef std::vector<int> IntVec;
std::vector<IntVec> a;
IntVec b;
boost::for_each(a,
boost::bind(boost::copy<IntVec,
std::back_insert_iterator<IntVec> >, _1, std::back_inserter(b)));
}
Lyrics:
I try to implement a task pool over MPI. So I need some kind of RPC but one that would work between different parts of my program, meaning processor A wants processor B to call function C with argument D. We can not pass pointers to functions between processes like we do with threads, so we need some wrapper container to hold our function pointers at each process instance. All inside one source file\one program... So I started wondering about How to store functional objects with different signature in a container. My API Idea back then was wrong - it is better to define all functions in function pool at that pool construction (at least it shall be much easier to implement). But while implementing I faced next trouble:
Problem:
Such simple code (function_types, mpl::vector, variant):
#include <boost/function_types/function_type.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/variant.hpp>
#include <iostream>
#include <string>
template <class T>
int append(T val)
{
std::cout << "hello";
return 0;
}
int main()
{
boost::variant<boost::function_types::function_type< boost::mpl::vector<int,int> >::type , boost::function_types::function_type< boost::mpl::vector<int,std::string> >::type > a;
return 0;
}
Will not compile falling with:
Error 1 error C2066: cast to function type is illegal c:\program files\boost\include\boost\variant\variant.hpp 1231 1
And looking at source we see:
this code block:
variant()
{
// NOTE TO USER :
// Compile error from here indicates that the first bound
// type is not default-constructible, and so variant cannot
// support its own default-construction.
//
new( storage_.address() ) internal_T0();
indicate_which(0); // zero is the index of the first bounded type
}
So I wonder: How to get around this error?
Also I tried:
#include <boost/function_types/function_type.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/variant.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <string>
template <class T>
int append(T val)
{
std::cout << "hello";
return 1;
}
int main()
{
boost::variant< boost::function<int (std::string) >, boost::function<int (int) > > a;
a= &append<int>;
return 0;
}
Which fails with:
Error 1 error C2668: 'boost::detail::variant::make_initializer_node::apply<BaseIndexPair,Iterator>::initializer_node::initialize' : ambiguous call to overloaded function c:\program files\boost\include\boost\variant\variant.hpp 1330
Any Ideas on how to make boost.variant hold functions?
Of course we can play with shared pointers to functors like so:
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <string>
template <class in, class out>
struct s_append
{
out operator()(in val) {
std::cout << "hello";
return out();
}
};
int main()
{
boost::variant<boost::shared_ptr<s_append<int, int> >, boost::shared_ptr< s_append<std::string, int> > > a;
boost::shared_ptr<s_append<int, int> > b(new s_append<int, int> );
a=b;
return 0;
}
and it would compile but resulting API sucks - you have to 1) create functors for all functions you want to use (meaning limit there use of current process scope); 2) use shared_pointers and so I don't really even get how to call functions nested that way (simple first guess (*a)(22); just won't compile =( and API starts to be as bad as we would have using Boost.Any).
Try inserting a dummy type as the first argument of the variant. As the comment you found explains, only the first type in the variant is used for the variant's own default constructor. You could use an empty struct type for this (struct NoFunction {};).
That said, you may have been onto something with the idea to use boost::functions as the types in the variant...they are default-constructible at least. I'm not sure what the other error you had from that approach was caused by, but just wanted to let you know you could pursue that angle more if you can't use the dummy-type workaround I mentioned.
I'm working on a C++ program for class, and my compiler is complaining about an "ambiguous" function call. I suspect that this is because there are several functions defined with different parameters.
How can I tell the compiler which one I want? Aside from a case-specific fix, is there a general rule, such as typecasting, which might solve these kinds of problems?
Edit:
In my case, I tried calling abs() inside of a cout statement, passing in two doubles.
cout << "Amount is:" << abs(amountOrdered-amountPaid);
Edit2:
I'm including these three headers:
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
Edit3:
I've finished the program without this code, but in the interest of following through with this question, I've reproduced the problem. The verbatim error is:
Call to 'abs' is ambiguous.
The compiler offers three versions of abs, each taking a different datatype as a parameter.
What's happened is that you've included <cstdlib> (indirectly, since it's included by iostream) along with using namespace std;. This header declares two functions in std with the name abs(). One takes and returns long long, and the other returns long. Plus, there's the one in the global namespace (that returns int) that comes from <stdlib.h>.
To fix: well, the abs() that takes double is in <cmath>, and that will actually give you the answer you want!
The abs function included by <cstdlib> is overloaded for int and long and long long. Since you give a double as the argument, the compiler does not have an exact fit, so it tries to convert the double to a type that abs accepts, but it does not know if it should try to convert it to int, long, or long long, hence it's ambiguous.
But you probably really want the abs that takes a double and returns a double. For this you need to include <cmath>. Since the double argument matches exactly, the compiler will not complain.
It seems that <cstdlib> gets included automatically when you include the other headers which should not happen. The compiler should have given error: ‘abs’ was not declared in this scope or something similar.
Try using fabs defined in <cmath>. It takes float, double and long double as arguments. abs is defined both in <cmath> and <cstdlib>. The difference is abs(int), abs(long) and abs(long long) are defined in <cstdlib> while other versions are defined in <cmath>.
Not sure why this isn't calling the int version of abs but you could try type casting the expression (amountOrdered - amountPaid) as int i.e.
cout <<"Amount is: "<< abs( (int)(amountOrdered - amountPaint) );