I am a beginner in C++ and want to do simple example of composite function.
For example, in MATLAB, I can write
a = #(x) 2*x
b = #(y) 3*y
a(b(1))
Answer is 6
I searched following questions.
function composition in C++ / C++11 and
Function Composition in C++
But they are created using advanced features, such as templates, to which I am not much familiar at this time. Is there a simple and more direct way to achieve this? In above MATLAB code, user does not need to know implementation of function handles. User can just use proper syntax to get result. Is there such way in C++?
** Another Edit:**
In above code, I am putting a value at the end. However, if I want to pass the result to a third function, MATLAB can still consider it as a function. But, how to do this in C++?
For example, in addition to above code, consider this code:
c = #(p,q) a(p)* b(q) %This results a function
c(1,2)
answer=12
d = #(r) a(b(r))
d(1)
answer=6
function [ output1 ] = f1( arg1 )
val = 2.0;
output1 = feval(arg1,val)
end
f1(d)
answer = 12
In this code, c takes two functions as input and d is composite function. In the next example, function f1 takes a function as argument and use MATLAB builtin function feval to evaluate the function at val.
How can I achieve this in C++?
How about:
#include <iostream>
int main(int, char**)
{
auto a = [](int x) { return 2 * x; };
auto b = [](int y) { return 3 * y; };
for (int i = 0; i < 5; ++i)
std::cout << i << " -> " << a(b(i)) << std::endl;
return 0;
}
Perhaps I'm misunderstanding your question, but it sounds easy:
int a(const int x) { return x * 2; }
int b(const int y) { return y * 3; }
std::cout << a(b(1)) << std::endl;
Regarding your latest edit, you can make a function return a result of another function:
int fun1(const int c) { return a(c); }
std::cout << fun1(1) << std::endl;
Note that this returns a number, the result of calling a, not the function a itself. Sure, you can return a pointer to that function, but then the syntax would be different: you'd have to write something like fun1()(1), which is rather ugly and complicated.
C++'s evaluation strategy for function arguments is always "eager" and usually "by value". The short version of what that means is, a composed function call sequence such as
x = a(b(c(1)));
is exactly the same as
{
auto t0 = c(1);
auto t1 = b(t0);
x = a(t1);
}
(auto t0 means "give t0 whatever type is most appropriate"; it is a relatively new feature and may not work in your C++ compiler. The curly braces indicate that the temporary variables t0 and t1 are destroyed after the assignment to x.)
I bring this up because you keep talking about functions "taking functions as input". There are programming languages, such as R, where writing a(b(1)) would pass the expression b(1) to a, and only actually call b when a asked for the expression to be evaluated. I thought MATLAB was not like that, but I could be wrong. Regardless, C++ is definitely not like that. In C++, a(b(1)) first evaluates b(1) and then passes the result of that evaluation to a; a has no way of finding out that the result came from a call to b. The only case in C++ that is correctly described as "a function taking another function as input" would correspond to your example using feval.
Now: The most direct translation of the MATLAB code you've shown is
#include <stdio.h>
static double a(double x) { return 2*x; }
static double b(double y) { return 3*y; }
static double c(double p, double q) { return a(p) * b(q); }
static double d(double r) { return a(b(r)); }
static double f1(double (*arg1)(double))
{ return arg1(2.0); }
int main()
{
printf("%g\n", a(b(1))); // prints 6
printf("%g\n", c(1,2)); // prints 12
printf("%g\n", d(1)); // prints 6
printf("%g\n", f1(d)); // prints 12
printf("%g\n", f1(a)); // prints 4
return 0;
}
(C++ has no need for explicit syntax like feval, because the typed parameter declaration, double (*arg1)(double) tells the compiler that arg1(2.0) is valid. In older code you may see (*arg1)(2.0) but that's not required, and I think it makes the code less readable.)
(I have used printf in this code, instead of C++'s iostreams, partly because I personally think printf is much more ergonomic than iostreams, and partly because that makes this program also a valid C program with the same semantics. That may be useful, for instance, if the reason you are learning C++ is because you want to write MATLAB extensions, which, the last time I checked, was actually easier if you stuck to plain C.)
There are significant differences; for instance, the MATLAB functions accept vectors, whereas these C++ functions only take single values; if I'd wanted b to call c I would have had to swap them or write a "forward declaration" of c above b; and in C++, (with a few exceptions that you don't need to worry about right now,) all your code has to be inside one function or another. Learning these differences is part of learning C++, but you don't need to confuse yourself with templates and lambdas and classes and so on just yet. Stick to free functions with fixed type signatures at first.
Finally, I would be remiss if I didn't mention that in
static double c(double p, double q) { return a(p) * b(q); }
the calls to a and b might happen in either order. There is talk of changing this but it has not happened yet.
int a(const int x){return x * 2;}
int b(const int x){return x * 3;}
int fun1(const int x){return a(x);}
std::cout << fun1(1) << std::endl; //returns 2
This is basic compile-time composition. If you wanted runtime composition, things get a tad more involved.
Related
I've seen this used by other people and it looks really clever, but I'm not sure if it's good or bad practice. It works, and I like the way it works, personally, but is doing this actually useful in the scope of a larger program?
What they've done is dynamically allocate some data type inside the actual function argument, and delete it in the function. Here's an example:
#include <iostream>
class Foo {
private:
int number;
public:
Foo(int n) : number(n) { }
int num() { return number; }
Foo* new_num (int i) { number = i; }
};
void some_func (int thing, Foo* foo);
int main() {
std::cout << "Enter number: ";
int n;
std::cin >> n;
some_func(n, new Foo(0)); // <-- uses the 'new' operator with a function argument
return 0;
}
// calculates difference between 'thing' and 'n'
// then puts it inside the Foo object
void some_func (int thing, Foo* foo) {
std::cout << "Enter another number: ";
int n;
std::cin >> n;
std::cout << "Difference equals " << foo->new_num(thing - n)->num() << std::endl;
delete foo; // <-- the Foo object is deleted here
}
I knew that it was possible to use operators in function arguments, but I was only aware of doing this with the operators on levels 2, 4 through 15, and 17, as well as the assignment operators, ? :, ++ and --, unary + and -, !, ~, * and &, sizeof and casts. Stuff like this:
foo((x < 3)? 5 : 6, --y * 7);
bar(player->weapon().decr_durability().charge(0.1), &shield_layers);
So, I actually have two questions.
Is the new-as-an-argument good practice?
Since apparently any operator returning a type works if new works, are using these good practice?
::, new [], throw, sizeof..., typeid, noexcept, alignof
No, this is not clever at all. It takes a function that could be simpler and more general and reduces its capabilities for no reason, while at the same time creating an entry point into your program for difficult-to-debug bugs.
It's not clear to me exactly what Foo::new_num is meant to do (right now it doesn't compile), so I won't address your example directly, but consider the following two code samples:
void bad_function(int i, F * f)
{
f->doSomething(i);
delete f;
}
// ...
bad_function(0, new F(1, 2, 3));
versus
void good_function(int i, F & f)
{
f.doSomething(i);
}
// ...
good_function(0, F(1, 2, 3));
In both cases you allocate a new F object as part of the method call and it's destroyed once you're done using it, so you get no advantage by using bad_function instead of good function. However there's a bunch of stuff you can do with good_function that's not so easy to do with bad_function, e.g.
void multi_function(const std::vector<int> & v, F & f)
{
for(int i : v) { good_function(i, f); }
}
Using the good_function version means you're also prevented by the language itself from doing various things you don't want to do, e.g.
F * f; // never initialized
bad_function(0, f); // undefined behavior, resulting in a segfault if you're lucky
It's also just better software engineering, because it makes it a lot easier for people to guess what your function does from its signature. If I call a function whose purpose involves reading in a number from the console and doing arithmetic, I absolutely do not expect it to delete the arguments I pass in, and after I spent half an hour figuring out what's causing some obscure crash in some unrelated part of the code I'm going to be furious with whoever wrote that function.
By the way, assuming that F::doSomething doesn't alter the value of the current instance of F in any way, it should be declared const:
class F
{
void doSomething(int i) const;
// ...
};
and good_function should also take a const argument:
void good_function(int i, const F & f);
This lets anyone looking at the signature confidently deduce that the function won't do anything stupid like mess up the value of f that's passed into the function, because the compiler will prevent it. And that in turn lets them write code more quickly, because it means there's one less thing to worry about.
In fact if I see a function with a signature like bad_function's and there's not an obvious reason for it, then I'd immediately be worried that it's going to do something I don't want and I'd probably read the function before using it.
I am trying to do a simple library where the object is a point on the xy-axis.
I want to be able to use literals like this:
Point a = (3,4);
where (3,4) is a point literal.
I read about user defined literals, but (as I understood) this seems to be impossible.
May be "(3,4)"_P is possible as I understand it.
However, I found on this page interesting use of user defined literals as follows:
#include <iostream>
#include <complex>
int main()
{
using namespace std::complex_literals;
std::complex<double> c = 1.0 + 1i;
std::cout << "abs" << c << " = " << abs(c) << '\n';
}
I can under stand the part 1i as a user defined literal, but not the whole thing 1.0 + 1i.
What I am missing, and what is the nearest possible way of getting a literal similar to (x,y) without using ".
As Some programmer dude shows, the best way is to use uniform initialization.
However, just for the fun of it, you can (sort of) do this with User Defined Literals. My idea is to to have 2 literals for each coordinate and overload operator+ between them to create the point.
Remember, this is just for fun, don't use this in a real code:
struct Px { int x; };
struct Py { int y; };
struct Point {
int x;
int y;
};
constexpr auto operator""_px(unsigned long long x) -> Px { return Px{(int)x}; }
constexpr auto operator""_py(unsigned long long y) -> Py { return Py{(int)y}; }
constexpr auto operator+(Px x, Py y) -> Point { return Point{x.x, y.y}; }
then you can have:
auto p = 3_px + 4_py; // p is deduced to type `Point`
Of course this is just a rough framework. Read this great article to learn more about UDLs. You would need to deal with the narrowing conversion in a better way and propper use namespaces to make it a better solution.
As a bonus, you could also use operator, to create a syntax more appropriate to what you had in mind. But, don't do this, as overloading operator, is just evil:
auto operator,(Px x, Py y) -> Point { return Point{x.x, y.y}; }
auto p = (2_px, 1_py); // p is deduced to type `Point`
You can't make up literals on your own, only create suffixes for literals. Like the shown 1i or the standard language f as in 1.0f. (See e.g. this user-defined literal reference for more information.)
What you can to is to use uniform initialization doing something like
Point a = { 3, 4 }; // note the use of curly-braces
Depending on what Point is you might need to add a suitable constructor to make it work.
You have 3 options
Point p = { 1,2 };
Point p2{ 1,2 };
Point p3(1,2);
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
The code snippet is as follows
#include <iostream>
using namespace std;
int a(int m)
{
return ++m;
}
int b(int &m)
{
return ++m;
}
int c(int &m)
{
return ++m;
}
int main(void)
{
int p=0,q=0,r=0;
p+=a(b(p));
q+=b(a(q));
r+=a(c(r));
cout<<p<<q<<r;
return 0;
}
The error occurring is invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int' at q+=b(a(q)). How to go about the error so that this program prints a desired output
Timothy J Williams is one or both of the following things:
wrong;
teaching C++ as it pertains to Visual Studio only, without disclaiming it, which is ill-advised.
References cannot bind to temporaries. It is not allowed in C++. Visual Studio allows it as a non-standard extension, but that's it. Some people get confused and think that means it's valid C++. It's not.
You will have to store the results of function calls like b(1) into named variables before you pass them anywhere by reference.
int main()
{
int p = 0, q = 0, r = 0;
int result_of_b_p = b(p);
p += a(result_of_b_p);
int result_of_a_q = a(q);
q += b(result_of_a_q);
int result_of_c_r = c(r);
r += a(result_of_c_r);
std::cout << p << q << r << '\n';
}
I should also note that the cited code is confusing and appears to serve no purpose other than for contrived "test your knowledge" challenges. I'd pay not too much attention to this and instead learn C++ from a proper book. After all, Timothy Williams claims that the above program outputs 322; it doesn't.
You cannot pass by reference a constant.
To break down your code.
int a(int m){
return ++m;
}
This will return an int (constant, eg. 5)
Then in
int b(int &m){
return ++m;
}
You are now technically passing in an integer (constant) not a variable into B. You must pass B in as a variable.
Try exactly what you have but passing in
int x = a(your_number_here);
int z = b(x);
EDIT:
int main(void){
int p=0,q=0;
int x = 5;
p = a(x);
q = b(p);
cout << q << endl;
return 0;
}
Returns 7.
The error is a result of trying to call a function that takes a reference with a value. It would be like calling b with a value literal b(1). That can't work...
The function call is where you pass by reference. See below:
void foo (int* m)
{
(*m)++;
}
int main (void)
{
int a = 0;
foo (&a);
cout << a << endl; // prints 1
}
So here b(int& m) takes a reference to an integer. Think about it this way. A reference is a "safe pointer" for which the compiler automatically handles the dereferencing operations.
The return value of a(int m) is a temporary, i.e. it is a temporary value that goes out of scope as soon as the function returns and its value has been utilized in some way. So you can do x = a(15); and x will become a copy of the returned 16. This is what an r-value is. A sort of "temporary" (r because it is on the right side of the expression). So when you have a pointer to a temporary value it does not make sense in most cases. For example in the following code
int* return_local() {
int a = 10;
return &a;
}
This will give you a compiler warning. Because you don't want to bind a pointer to a value which will go out of scope. Similarly you don't want a reference to an object that will go out of scope as soon as the function has returned and its value has been utilized. That is why there is an error in your code. a(int m) returns an r-value and when you do b(a(q) you are trying to bind a reference to an r-value
Now there is something called an r-value reference which takes the form void some_func(int&& rvalue_reference) in syntax. The && means r-value reference not reference to reference. Look it up if you are interested.
It's not allowed to pass a r-value as a non-const reference argument. This happens in the line whereyou call the function b with a(q) as its argument, which is an r-value (an expression which is not a simple variable).
So you need to first call a and store itsvalue in a variable, and then pass this variable to b:
int main(void)
{
int p=0,q=0,r=0;
p+=a(b(p));
int t=a(q);
q+=b(t);
r+=a(c(r));
cout<<p<<q<<r;
return 0;
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I had to convert a C++ program to C, which has been done. The question is whether the codes presented are equivalent and whether I missed anything.
Both codes presented are complete and should compile. Both give the same answers when run, too. But I am new to C++ and I don't know if I missed something in my conversion that might be important.
One more question, in the C++ code, int x and int y were declared as global, I don't have, and don't think I need anything analogous to that, but I don't really know what they are doing. Guidance?
C++
#include <iostream>
// a point on the integer grid
struct Point
{
// constructor
Point()
{
x = y = 0;
}
// add point componentwise
void add(const Point &p)
{
x += p.x;
y += p.y;
}
// print to standard output
void print() const
{
std::cout << "[" << x << "," << y << "]" << std::endl;
}
// data
int x, y;
};
int main()
{
const int N = 200;
Point *A = new Point[N], sum;
for (int i=0; i < N; ++i) {
sum.print();
A[i].x = i; A[i].y = -i;
sum.add(A[i]);
}
sum.print();
delete [] A;
}
C
#include <stdio.h>
#include <stdlib.h>
typedef struct //constructor
{
int x;
int y;
} Point;
void add(const Point * p, Point * sum)
{
(*sum).x += (*p).x;
(*sum).y += (*p).y;
}
void print(const int x, const int y)
{
printf("[%d,%d]\n", x, y);
}
int main()
{
int i = 0;
const int N = 200;
Point *A = malloc(N*sizeof(Point)), sum;
if(!A)
{
printf(stderr, "malloc() failed to allocate memory!");
abort();
}
sum.x =0;
sum.y = 0;
for (i = 0; i <N; i++)
{
print (sum.x, sum.y);
A[i].x = i; A[i].y = -i;
add(&A[i], &sum);
}
print(sum.x, sum.y);
free(A);
return 0;
}
It is fairly equivalent functionally (aside from the constructor issue, see below). But for some reason it contains a number of inconsistencies and "illogical" stylistic decisions.
The "standard" approach to approximate a C++ method by a C function is to implement the C++ implicit this parameter through an explicit parameter. That would make your add function look as follows
void add(Point *this, const Point *p)
{
this->x += p->x;
this->y += p->y;
}
Note that in C++ version you could also use the this->x syntax on the left-hand side (instead of just x), which would only emphasize the similarity. Obviously, my version above is the same as yours, but arranged in what I believe is more "traditional" fashion.
You forgot to define a "constructor" for your Point in C version of the code. In C++ code your Point objects begin their lives initialized to zero. In C code these objects begin their lives with garbage in x and y. Later you assign definitive values to x and y, which makes the non-initialization issue non-consequential, but still it is there.
Of course, if you decide to implement a "constructor" function, you will have to call it manually for each array element, while in C++ it is called automatically for you.
For some reason you decided to "disassemble" the object into x and y parameters for print function. Why? Again, the same approach with an explicit this parameter can be used for print and it would look as follows
void print(const Point *this)
{
printf("[%d,%d]\n", this->x, this->y);
}
In your current version
void print(const int x, const int y)
const qualifiers applied to parameters achieve virtually nothing useful and do not promote equivalence to the C++ version (i.e. these const qualifiers are not equivalent to that trailing const in the C++ version).
But, in any case, these are purely stylistic suggestions.
Note also that in C++ language
const int N = 200;
defines a constant, while in C language it does not define a constant. In C it defines what essentially is a "non-modifiable variable". But this is completely non-consequential for your code, since your code does not care whether N is a constant or not. (I don't know whether you care about this sort of pedantic equivalence.)
It depends on the level of 'equivalency' you're looking for. In the C version you don't have a function equivalent to the Point constructor and you avoid the default initialization on the array of points, your C print function operates on ints instead of a Point object, and I see some const mismatches such as the fact that your C add function takes a pointer to non-const Point on the right hand side while the C++ version takes a reference to const Point.
I had a simple question and was hoping for the underlying logic behind passing by reference.
Here's one code (let's call it Code1):
void fn(int& a)
{
a = 6;
}
int main()
{
int b = 5;
fn(b);
cout << b;
}
Here's another code (Code2):
void fn(int* ptr)
{
*ptr = 6;
}
int main()
{
int b = 5;
fn(&b);
cout << b;
}
And a pass by value code (Code 3):
void fn(int a)
{
a = 6;
}
int main()
{
int b = 5;
fn(b);
cout << b;
}
Here goes my question. Intuitively, I see that while passing by value (Code3), the values are copied ie a would just have taken/copied into itself the value of b. Thus, as a general rule, I see that value passed is just copied always to the called function (here fn). Even with the pointer code (ie Code2), the first line of Code 2 ensures that int *ptr = &a;
I don't understand how this would work in Code1. Saying that &a = b makes no sense. Is this an exception, or does this fit into a rule that is consistent with the cases discussed in the paragraph above?
Thanks!
In this function:
void fn(int &a) {
a=6;
}
the term "&a" does not mean "the address of the variable a". It means "a reference called a". Code 1 and Code 2 are effectively the same (but note that the function in Code 2 can be passed an invalid pointer, which is (almost) impossible for Code 1).
For most intents and purposes, a reference is just a pointer in disguise. Different syntax, same effect (mostly).
Conceptually, in your first case what happens is that the same variable has two labels: b, visible within the scope of main(); and a, visible within the scope of fn.
You don't have to worry about what the compiler does "behind the scenes" to implement this concept.
If you mentally promote the compiler's "behind the scenes" actions to actually being imagined principles of C++, e.g. "the reference is a pointer in disguise", then it leads you to get confused about what is actually a pretty simple concept: the ability to give multiple names to a variable.
It is nothing special being a function parameter; e.g. you could write in main():
int a;
int &c = a;
which is exactly equivalent to:
int c;
int &a = c;
In both cases there is an int variable with two labels, a and c.