I have a strange metafunction behavior in my C++ code and I want to understand why.
#include <iostream>
#include <cmath>
inline double f(double x, double y)
{
std::cout<<"Marker"<<std::endl;
return sqrt(x*y);
}
template <int N, class T> inline T metaPow(T x)
{
return ((N > 0) ? (x*metaPow<((N > 0) ? (N-1) : (0))>(x)) : (1.));
}
int main()
{
double x;
double y;
std::cin>>x;
std::cin>>y;
std::cout<<metaPow<5>(f(x, y))<<std::endl;
return 0;
}
I expected that the line metaPow<5>(f(x, y)) was equivalent to f(x, y)*f(x, y)*f(x, y)*f(x, y)*f(x, y)*1.. But if it was, it would print me five times the "Marker" line in the f function.
The strange thing is that I have the good result at the end (for example 181.019 for x = 2 and y = 4) but I have only 1 "Marker" displayed. How is it possible ? And consequently is it a good option to use that function for compile-time optimization instead of the standard pow() ?
Thank you very much !
I believe that f(x,y) is being evaluated before being passed in to your metaPow function. So the x argument to metaPow is just the value sqrt*(8). metaPow is never calling f(x,y). Hence, f(x,y) is only called once - when you initially call metaPow in your main function.
I think:
metaPow<5>(f(x, y))
equals to
double z = f(x, y); metaPow<5>(z);
Related
I am using a library for an optimizer (Brent's method) that has a function "local_min".
Its prototype is defined roughly as follows:
double local_min ( double f ( double x ) );
The function accepts a function pointer (?) as a parameter. Suppose f(x) is the function... the optimizer will test various values for x to find a minimum value for f(x).
The local_min function is called such as:
double f(double x){
return .5 + x * x;
}
int main(){
double fx = local_min(f);
return 0;
}
The trouble I am having is that I want to define the .5 as a scalar for the function, but I do not want to use global values. Ideally, I would have everything in a single class. But everything I try, I change the function signature of f(x) and it will no longer be accepted by local_min().
For example:
int main(){
double value = 0.5;
auto lambda = [](double x) {
return value + x * x;
};
double fx = local_min(f);
return 0;
}
does not work because value is not accessible. Similarly,
int main(){
double value = 0.5;
auto lambda = [&](double x) {
return value + x * x;
};
double fx = local_min(f);
return 0;
}
changes the function signature and is no longer accepted by local_min().
Instead of a function pointer, make local_min accept an arbitrary type. This will let you pass it a lambda with captures as desired
template<typename F>
double local_min(F f)
{
// ... same usage as before
}
The callable f will still behave the same way as before, i.e. like a function that takes a double and returns a double. If you call local_min with an incompatible type, it will fail to compile. You can check for this with a static_assert to give the user a nice error message if you want.
I am supposed to write a function name double_swap that takes two doubles as arguments and interchanges the values that are stored in those arguments. The function should return no value, so I know that means it must be a void function.
For example, if the following code fragment is executed,
int main()
{
double x = 4.8, y = 0.7;
double_swap(x,y);
cout<<"x = "<<x<<" y = "<<y;
}
The output will be:
x = 0.7 y = 4.8
The program I wrote is not swapping the values. I'd greatly appreciate if someone could point out my errors.
#include <iostream>
using namespace std;
void double_swap(double x, double y)
{
x = 1.9;
y = 4.2;
}
int main()
{
double x = 4.2, y = 1.9;
double_swap(x,y);
cout<<"x = "<<x<<" y = "<<y<<endl;
return 0;
}
You need to pass the variables by reference in order for the modifications in the function to apply to the variables from the call site. As it is right now all you are doing is modifying copies that get destroyed once the function ends.
Change
void double_swap(double x, double y)
to
void double_swap(double& x, double& y)
Also instead of hard coding the values lets do a real swap using
void double_swap(double& x, double& y)
{
double temp = x;
x = y;
y = temp;
}
You could also use pointers for the function paramters for this but then your call site would have to be changed to double_swap(&x,&y); and you would have to remember to reference the pointers in the function.
Instead of doing all of this though we can just use std::swap and let it do this for us.
When calling a function in c++ , There is 3 way to pass the parameters. The first one is by Copy where it only make a copy of the variable in parameters and then delete them.
void double_swap(double x, double y)
The second one is by Reference, where the paramaters refere to the real variable (Whats you want).
void double_swap(double& x, double& y)
And the last one is by address where you pass the address of the variables.
void double_swap(double* x, double* y)
I have a long algorithm that should process some instruction described from more than one #define in order to reduce drastically my source-code. For example:
#define LongFunction(x, y, alg) return alg(x, y)
#define Alg1(x, y) ((x)+(y))
#define Alg2(x, y) ((x)^((x)-(y)))
And all I need to do is
LongFunction(x, y, Alg1);
LongFunction(x, y, Alg2);
I'd like to not pass a function as parameter because LongFunction is full of loops and I want that the code will be as fast as possible. How can I accomplish this task smartly?
There are many ways to parameterize on function.
Using macros might seem simple, but macros don't respect scopes, and there are problems with parameter substitution and side-effects, so they're Evil™.
In C++11 and later the most natural alternative is to use std::function and lambdas, like this:
#include <functional> // std::function
#include <math.h> // pow
using std::function;
auto long_function(
double const x,
double const y,
function<auto(double, double) -> double> alg
)
-> double
{
// Whatever.
return alg( x, y ); // Combined with earlier results.
}
auto alg1(double const x, double const y)
-> double
{ return x + y; }
auto alg2(double const x, double const y)
-> double
{ return pow( x, x - y ); }
#include <iostream>
using namespace std;
auto main() -> int
{
cout << long_function( 3, 5, alg1 ) << endl;
}
Regarding “fast as possible”, with a modern compiler the macro code is not likely to be faster. But since this is important, do measure. Only measurements, for release build and in the typical execution environment, can tell you what's fastest and whether the speed is relevant to the end user.
Of old, and formally, you could use the inline specifier to hint to the compiler that it should machine code inline calls to a function. Modern compilers are likely to just ignore inline for this (it has another more guaranteed meaning wrt. ODR). But it probably won't hurt to apply it. Again, it's important to measure. And note that results can vary with compilers.
One alternative to the above is to pass a simple function pointer. That might be faster than std::function, but is less general. However, in the other direction, you can templatize on a type, with a member function, and that gives the compiler more information, more opportunity to inline, at the cost of not being able to e.g. select operations from array at runtime. I believe that when you measure, if this is important enough, you'll find that templatization yields fastest code. Or at least as fast as the above.
Example of templatizing on a type that provides the operation:
#include <math.h> // pow
template< class Op >
auto long_function( double const x, double const y )
-> double
{
// Whatever.
return Op()( x, y ); // Combined with earlier results.
}
struct Alg1
{
auto operator()(double const x, double const y)
-> double
{ return x + y; }
};
struct Alg2
{
auto operator()(double const x, double const y)
-> double
{ return pow( x, x - y ); }
};
#include <iostream>
using namespace std;
auto main() -> int
{
cout << long_function<Alg1>( 3, 5 ) << endl;
}
By the way, note that ^ is not an exponentiation operator in C++ (it is in e.g. Visual Basic). In C and C++ it's a bitlevel XOR operator. In the code above I've assumed that you really meant exponentiation, and used the pow function from <math.h>.
If, instead, you really meant bitlevel XOR, then the arguments would need to be integers (preferably unsigned integers), which then would indicate that you want argument types for long_function depending on the argument types for the specified operation. That's more thorny issue, but involves either overloading or templating, or both. If that's what you really want then please do elaborate on that.
For example, I have a simple macro
#define MIN(a, b) (a) < (b) ? (a) : (b)
and I want to use
MIN(pow(2, 3) , 10);
The internal common gives trouble. I can do as following
int a = pow(2, 3);
MIN(a, 10);
I am looking for a better way that is more readable by like keeping pow(2, 3) in the macro? Is it possible? Thanks!
You can use std::min instead:
#include <algorithm>
//...
double x = std::min(pow(2, 3) , 10);
Generally, you should prefer an inline function over a macro. If the purpose of the macro is to allow it to work for a variety of types, you can use a template.
template <typename T>
inline T SomeFunction (T x, T y) {
T result;
//...do something with x and y and assign to result
return result;
}
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
C++ — return x,y; What is the point?
Here's a piece of code that executes perfectly in C.
int a=3,b=4,x,y;
x=a+b;
y=a*b;
return(x,y);
This function returns 12. Can someone please explain.
This is because you (inadvertently) use the comma operator, whose value is that of the last expression included. You can list as many expressions as you like, separated by the comma operator, the result is always that of the last expression. This is not related to return; your code can be rewritten like
int tmp = (x, y); // x = 7, y = 12 -> tmp is assigned 12
return tmp;
[Updated] You don't usually need brackets around the list, but here you do, due to the assignment operator having a higher precedence than comma - kudos to #Draco for pointing it out.
Edit : This answers the title Q, viz 'can return return multiple values'
Not exactly. You can
return the second variable by using reference (or pointer) parameter
otherwise, create a new class or struct containing x and y and return an instance of this new class
No, you cannot return multiple values simply by using (x, y) — this is not a tuple, as you might expect from other languages, but a bracketed use of the comma operator, which will simply evaluate to y (which will, in turn, be returned by the return).
If you want to return multiple values, you should create a struct, like so:
#include <stdio.h>
struct coordinate
{
int x;
int y;
};
struct coordinate myfunc(int a, int b)
{
struct coordinate retval = { a + b , a * b };
return retval;
}
int main(void)
{
struct coordinate coord = myfunc(3, 4);
printf("X: %d\n", coord.x);
printf("Y: %d\n", coord.y);
}
This shows the full syntax of using a struct, but you can use typedef if you prefer something like:
typedef struct
{
int x;
int y;
} coordinate;
coordinate myfunc(int a, int b)
{
coordinate retval = { a + b , a * b };
return retval;
}
// ...etc...
The answer to your question is "no, return cannot return multiple values". Here you see the result of the evaluation of the legal expression x,y, which is y i.e. 3*4 = 12.
The comma operator is just a binary operator. The right-most value is returned.
That's the comma operator. It evaluates its left side, then evaluates its right side, and its resulting value is the right side.
So, return(x,y) is the same as return y, since evaluating x has no side-effects.
The only way to "return multiple values" in C is to return a struct by value:
#include <stdio.h>
typedef struct {
int sum;
int product;
} sumprod;
sumprod get_sum_and_product(int x, int y) {
sumprod ret = {x + y, x * y};
return ret;
}
int main() {
sumprod values = get_sum_and_product(3,4);
printf("sum is %d, product is %d\n", values.sum, values.product);
}