using namespace std;
double func(double a, double b)
{
return a - b;
}
int main()
{
double result = (boost::bind(&func, _1, _2))(1,0, 2.0);
cout << "a: " << result << endl;
result = (boost::bind(&func, _2, _1))(1,0, 2.0);
cout << "b: " << result << endl;
return 0;
}
Output:
a: 1
b: -1
I think it is the simplest boost::bind example.
But it acts weird not as I expect.
I'm using boost_1.58_0, gcc 4.8.4.
Could anybody tell me why those place holders are switched ??
You have a typo and are passing three arguments to the bound functor:
(1,0, 2.0);
This substitutes 1 for the _1 placeholder, and 0 for the _2 placeholder, and ignores the third argument, so func runs 1 - 0 which is 1.
For the second call you pass the same arguments, but they are passed to the wrapper functor in a different order so func runs 0 - 1 which is -1.
Related
I tried to raise stack overflow using template like the following :
#include <iostream>
using namespace std;
#define endl '\n'
template <class T>
// void next (T a) cout << a++ << endl; // can't write in a line without {}
void next (T a)
{
if (typeid(a) == typeid((char) 'a') || typeid(a) == typeid((unsigned char) 'a'))
{
cout << typeid(a).name() << " : " << (int) a << " + 1 = " << (int) ++a << " (converted to ASCII value)" << endl;
} else
{
cout << typeid(a).name() << " : " << a << " + 1 = " << ++a << endl;
}
// there will be more alternatives like type_info and so on ……
}
int main()
{
next((char) CHAR_MAX);
next((unsigned char) UCHAR_MAX);
next((short) SHRT_MAX);
next((unsigned short) USHRT_MAX);
next((int) INT_MAX);
next((unsigned int) UINT_MAX);
next((bool) 1); // warning: use of an operand of type 'bool' in 'operator++' is deprecated
return 0;
}
results :
c : 127 + 1 = -128 (converted to ASCII value)
h : 255 + 1 = 0 (converted to ASCII value)
s : 32767 + 1 = -32768
t : 65535 + 1 = 0
i : 2147483647 + 1 = -2147483648
j : 4294967295 + 1 = 0
b : 1 + 1 = 1
This is an advanced code from my previous one using overloading similar functions for each data type(so shame, so it should be secret).
But now I have more question if I can compress the series of next() in main() more. I think it seems to require a container that can have various typed data; for example, {short 1, int 10, long long 100}.
Thank you for your advices & above all, take care of your health.
Indeed, I have no idea what are you asking so I try to answer some related questions and hope this will help :)
To find a maximum value of a type T, use numeric_limits<T>::max() function instead of macros. This way you can only specify the type to call your function:
next<char>();
next<unsigned char>();
next<short>();
...
In the function next I can see how you handle char types in a special way. There is a neat trick that saves you from using if. Expression +a (unary plus) triggers integer promotion and thus will yield you at least type int, which is properly printable as a number. So you can rewrite next like this:
template <class T>
void next()
{
T a = std::numeric_limits<T>::max();
T b = a + 1;
std::cout << typeid(T).name() << " : " << +a << " + 1 = " << +b << std::endl;
}
Answering your original question, now when you got rid of macros in the calls of next you can "iterate" on the types to call it with. In c++ if you need a "collection of types" T1, T2, T3, you usually use std::tuple<T1, T2, T3>. However, in this particular case where you don't have to store this "collection" anywhere, it is actually easier to go with variadic templates and fold expressions:
template<class... Ts>
void print() {
(next<Ts>(), ...);
}
int main()
{
print<char, unsigned char, short, int>();
}
Note how expression (next<Ts>(), ...); expands into (next<char>(), next<unsigned char>(), next<short>(), next<int>());. This is a number of calls separated by operator comma.
As a final point, using ++a or a+1 to find a "next" number is incorrect, since overflowing signed integer types is undefined behavior. You won't necessarily get expected results.
I have the following:
void print_str(std::shared_ptr<std::string> str) {
std::cout << str->c_str() << std::endl;
}
int main() {
auto str = std::make_shared<std::string>("Hello");
std::function<void()> f = std::bind(print_str, str);
f(); // correctly print: Hello
return 0;
}
I think the type of std::bind(print_str, str) is std::function<void(std::shared_ptr<std::string>)>, but the code above is correctly running. Is there any trick in std::bind?
env: centos, gcc82
What std::bind does is correct. It uses the value you provided (str) for the call to print_str. So you don't need to specify it anymore and will always be replaced by the bound value.
#include <iostream>
#include <functional>
int sum(int value1, int value2) {
return value1 + value2;
}
int main() {
std::function<int(int, int)> f1 = std::bind(sum, std::placeholders::_1, std::placeholders::_1);
std::function<int(int)> f2 = std::bind(sum, 10, std::placeholders::_1);
std::function<int()> f3 = std::bind(sum, 100, 200);
std::function<int(int)> f4 = std::bind(sum, std::placeholders::_1, 200);
int a = 1;
int b = 2;
std::cout << "the sum of " << a << " and " << b << " is: " << f1(a, b) << std::endl;
std::cout << "the sum of " << 10 << " and " << b << " is: " << f2(b) << std::endl;
std::cout << "the sum of " << 100 << " and " << 200 << " is: " << f3() << std::endl;
std::cout << "the sum of " << 200 << " and " << b << " is: " << f4(b) << std::endl;
return 0;
}
output:
the sum of 1 and 2 is: 2
the sum of 10 and 2 is: 12
the sum of 100 and 200 is: 300
the sum of 200 and 2 is: 202
f1 binds no values but placeholders and returns an int(int, int) like function
f2 binds one value and one placeholder and returns an int(int) like function
f3 binds two values and no placeholder and returns an int() like function
f4 is like f2 except that the place holder is now the first parameter instead of the second one.
Your code falls into the f3 case.
I think the type of std::bind(print_str, str) is std::function<void(std::shared_ptr<std::string>)>
No, the type of std::bind(print_str, str) is an unspecified functor type, something like
class binder
{
void(*f)(std::shared_ptr<std::string>);
std::shared_ptr<std::string> p;
public:
template<typename... Args>
void operator()(Args... ) { f(p); }
};
Note that this is callable with any arguments or none.
What you are experiencing here is correct and is precisely doing what std::bind was designed for.
Simply speaking:
It turns a function taking n parameters into a function taking m parameters (where n >= m).
In your particular case, you give it a function taking one parameter and get back a function taking zero parameters. This new function will internally call print_str and always pass str as argument.
Side note:
Since there are lambdas in C++11, std::bind is sort of redundant.
What you are doing is exactly equivalent to this:
void print_str(std::shared_ptr<std::string> str) {
std::cout << str->c_str() << std::endl;
}
int main() {
auto str = std::make_shared<std::string>("Hello");
std::function<void()> f = [=]() { print_str(str); };
f(); // correctly print: Hello
return 0;
}
This hopefully also helps understanding what std::bind does behind the scenes.
Could you explain me how these functions work?
double f(int i)
{
cout<<"a";
return 1;
}
int f(double i)
{
cout<<"b";
return 1;
}
For:
f(f(f(1)));
In my opinion the result should be: aaa
but it isaba
And same situation with f(f(f(1.1)));
I think there should be aab but there is bab
When you return from a function, the type of the return value is determined from the function prototype, not what it's written as-is. If the type doesn't match, it'll be implicitly converted to the correct type. So this example function:
double foo(void) { return 1; }
Actually returns double(1), or equivalently, 1.0. It does not return an int because 1 is int. It does, however, convert your int to a double value to match the function's return value type as declared.
So coming to your question, the innermost function called is double f(int), and the second function called is int f(double), and the outermost function called is double f(int). This matched the output you see: aba.
f( f( f(1) ) );
↑ ↑ ↑
| | calls double f(int)
| calls int f(double)
calls double f(int)
The way the compiler reads your f(f(f(1))); function is from the inside out. Let me elaborate, the compiler sees f(1); and it looks for a function called f that takes an int as an argument so that would be:
double f(int i)
{
cout<<"a";
return 1;
}
Now, once your function executes, it returns a double, hence the second f takes in a double -> which calls your next function that takes double
int f(double i)
{
cout<<"b";
return 1;
}
Following the logic explained above, we have arrived at the last/outer layer of your triple f question. Now the compiler has an int and is looking for a function called f that takes int -> which is your first declared function.
And that is why you get aba as a result.
prior to your first use of std::cout in your code, add the line
std::cout << std::fixed;
This changes the output (of parameter i) quite a bit by causing int and double to show their 'true colors'. Perhaps this will illustrates what is happening.
Example:
double f(int i)
{
std::cout << " a" << std::setw(9) << i << " " << std::flush;
return 1;
}
int f(double i)
{
std::cout << " b" << std::setw(9) << i << " " << std::flush;
return 1;
}
int main(int , char** )
{
std::cout << std::fixed << "\n";
f(f(f(1)));
std::cout << std::endl;
f(f(f(1.0)));
return 0;
}
Generates output:
a 1 b 1.000000 a 1
b 1.000000 a 1 b 1.000000
The returned value (always integer 1) is implicitly transformed to the return type, which is different for the two functions.
Which function is invoked is determined by the signature of the function, i.e. the parameters actual type. This also illustrates that the return type is not part of the signature.
I am relatively new to c++ programming, I have an assignment to code the Newton Raphson method however I have the error error:
called object type 'double' is not a function or function pointer
This error appears when I am trying to compile my code. I tried some basic changes to assign pointer but I probably did it in the wrong way, my code is printed below, can anybody explain how can I overcome this?
#include <iostream>
#include <math.h>
using namespace std;
double f(double x); //this is f(x)
double f(double x) {
double eq1 = exp(x) + pow(x,3) + 5;
return eq1;
}
double f1(double x); //this is the first derivative f'(x)
double f1(double x) {
double eq2 = exp(x) + 3*pow(x,2);
return eq2;
}
int main() {
double x, xn, f, f1, eps;
cout << "Select first root :" << '\n'; //Here we select our first guess
cin >> xn;
cout << "Select Epsilon accuracy :" << '\n';
cin >> epsi;
f = f(x);
f1 = f1(x);
cout << "x_n" << " " << "x_(n+1)" << " " << "|x_(n+1) - x_1|" << '\n';
do {
x = xn; //This is the first iteneration step where x takes the value of the last itenarated (known) root xn
f = f(x);
f1 = f1(x);
xn = x - (f/f1); //this the formula that sets the itenaration going
cout << x << " " << xn << " " << fabs(xn - x) << '\n';
}
while( fabs(xn - x) < epsi ); //If |x_(n+1) - x_n| is smaller than the desired accurcay than the itenaration continues
cout << "The root of the equation is " << xn << '\n';
return 0;
}
Thank you
You have local variables with the same name as the functions, thus
f = f(x);
f1 = f1(x);
cannot work.
Rename either the functions or the variables. Anyhow single letter variable/function names are not nice. Use descriptive names. You (or anybody else) taking a look at the code after some weeks will be thankful for that.
PS: you also dont need the forward declarations. And the functions can be written a bit shorter:
//double f(double x); // this you dont need
double f(double x) {
return exp(x) + pow(x,3) + 5;
}
Also using namespace std; is considered bad practice. In this case it does little to no harm, but you better get rid of this bad habit before it does matter.
Last but not least you should format your code properly. This
while( fabs(xn - x) < epsi );
looks very nasty, because it seems to be an infinite loop. I almost never use the do-while loop, however, I suggest you to write it like this:
do {
// ...
} while ();
because usually whenever you see a while with a ; in the same line you should start to panic ;) (while loops are much more common than do-while and errors caused by a ; after the condition in a while loop can be a pain in the a** to debug)
You are attempting to use functions called f and f1 and doubles called f and f1. If you call the variables or the function something else, then you can resolve the error. It would be good coding practice to give these variables better names that tell the reader what they do and avoid mistakes like this one.
There were several errors in your code. I made it compilable:
#include <iostream>
#include <math.h>
using namespace std;
double func(double x); //this is f(x)
double func(double x) {
double eq1 = exp(x) + pow(x,3) + 5;
return eq1;
}
double func1(double x); //this is the first derivative f'(x)
double func1(double x) {
double eq2 = exp(x) + 3*pow(x,2);
return eq2;
}
int main() {
double x, xn, f, f1, eps;
cout << "Select first root :" << '\n'; //Here we select our first guess
cin >> xn;
cout << "Select Epsilon accuracy :" << '\n';
cin >> eps;
f = func(x);
f1 = func1(x);
cout << "x_n" << " " << "x_(n+1)" << " " << "|x_(n+1) - x_1|" << '\n';
do {
x = xn; //This is the first iteneration step where x takes the value of the last itenarated (known) root xn
f = func(x);
f1 = func1(x);
xn = x - (f/f1); //this the formula that sets the itenaration going
cout << x << " " << xn << " " << fabs(xn - x) << '\n';
}
while( fabs(xn - x) < eps ); //If |x_(n+1) - x_n| is smaller than the desired accurcay than the itenaration continues
cout << "The root of the equation is " << xn << '\n';
return 0;
}
The main problems were:
you defined the variable f with the same name of the f(x) function (the same error was repeated for the f'(x) function) and
you declared the eps variable to represent epsilon in your program but you tried to access to it several times by calling it epsi.
it's my first day messing around with C++. I'm trying to do just a really basic code looking for the roots in a quadratic equation. Here is my code so far:
#include <iostream>
#include <cmath>
int main () {
int a, b, c;
double root1, root2;
std::cout << "Enter the integers a, b, and c to fit in the quadratic equation: ax^2 + bx + c >> " << std::endl;
std::cout << "a = ";
std::cin >> a;
std::cout << "b = ";
std::cin >> b;
std::cout << "c = ";
std::cin >> c;
std::cout <<"\n";
std::cout << "Quadratic equation to solve is : " << a << "x^2 + " << b << "x + " << c <<std::endl;
root1 = (-b + sqrt(b*b - 4*a*c))/(2*a);
root2 = (-b - sqrt(b*b - 4*a*c))/(2*a);
if (root1 && root2 != nan) {
std::cout << "root 1 = " << root1 << std::endl;
std::cout << "root 2 = " << root2 << std::endl;
}
else
std::cout << "no root exists" << std::endl;
return 0;
}
I'm getting this error:
invalid operands to binary expression ('double' and 'double (*)(const char *)')
in the line:
if (root1 && root2 != nan)
I'm looking for a simple test to see if the roots exist and this obviously doesn't work. Thanks in advance for your help!
To check if something is a real number, use isnan:
if(!isnan(root1) && !isnan(root2))
Explanation:
isnan determines if the given floating point number arg is not-a-number (NaN). It returns true if arg is NaN, false otherwise.
The NaN values are used to identify undefined or non-representable values for floating-point elements, such as the square root of negative numbers or the result of 0/0. In C++, it is implemented with function overloads for each floating-point type, each returning a bool value.
double (*)(const char *) is a type which represents a pointer to a function that returns a double and takes a const char * argument. You'll find if you look at a reference for cmath that nan is the function in question.
Looks like you should be able to call it with an empty string to get a suitable value:
nan("")
However, you can't provide a double on one side of && and a bool on the other, so you'll need to have a suitable test for root1 as well.
And yes, that type syntax for nan is a bit crazy, that's how C does function pointer syntax, and the name of a function by itself represents a pointer to it, so that's what you get out of the compiler because C++ inherited C-style function pointers.
Use (C++11):
#include <cmath>
...
if (!isnan(root1) && !isnan(root2))
Use if (root1 != nan("") && root2 != nan(""))
The problem is in two places:
root1 is always true except when it is 0
nan is not declared, it should be nan("")
But I think it is better to use !isnan(root1) instead of just nan