i have a problem understanding how c++ syntax works.
#include<iostream>
using namespace std;
class Accumulator{
private:
int value;
public:
Accumulator(int value){this->value=value;}
Accumulator& add(int n){value+=n;}
int get(){return value;};
};
int main(int argc, char* argv[]){
Accumulator acc(10);
acc.add(5).add(6).add(7); //<-----how does this work?????
cout<<acc.get();
return 0;
}
this line: acc.add(5).add(6).add(7);
does it work left to right or the other way
something like acc.add(5) first and then do add(6)
i dont get it.
result is supposed to be 28.
thanks in advance.
edit:
weird, this code gets compiled successfully without any errors on g++.
i got this code from some non-english college c++ textbook. english is not my first language.
2nd edit: i now get the desired warnings after using -Wall option.
Your code doesn't compile, but if it did, it would work left to right. Add returns a reference to an Accumulator (it doesn't have a return value in your code, but it should probably return *this) so after you call
acc.add(5)
the return value is a reference to acc, which you can call add on again.
Here is a modified example with mult added that shows order of operations:
#include <iostream>
using namespace std;
class Accumulator{
private:
int value;
public:
Accumulator(int value){ this->value = value; }
Accumulator& add(int n){ value += n; return *this; }
Accumulator& mult(int n){ value *= n; return *this; }
int get(){ return value; };
};
int main(int argc, char* argv[]){
Accumulator acc(10);
acc.add(5).add(6).mult(7);
cout << acc.get();
return 0;
}
If it was right to left, the result would be 81, but it is left to right and the result is 147.
This is called Method chaining and is commonly seen in Fluent Interface pattern.
Each method call (acc.add(5)) returns a reference or pointer upon which successive method calls (.add(7)) can operate on.
Related
My Code doesnt work when I use cout inside a function but if I return the value and stream inside main function it works.
My code which does not work is
#include <iostream>
#include <cstring>
using namespace std;
int add(int a,int b){
int c = a+b;
cout<<c<<endl;
}
string add(string m,string n){
string c = m+" "+n;
cout<<c<<endl;
}
int main(){
string x ="amit";
string y ="kumar";
add(x,y);//adding string
add(5,58);//adding numbers
}
But when I return the value it works fine
#include <iostream>
#include <cstring>
using namespace std;
int add(int a,int b){
int c = a+b;
cout<<c<<endl;
}
string add(string m,string n){
string c = m+" "+n;
return c;
}
int main(){
string x ="amit";
string y ="kumar";
string z = add(x,y);
cout<<z<<endl;
add(5,58);//adding numbers
}
I am using Codeblocks for my programming. Why is this abrupt behaviour. What am I doing wrong here.
Both your programs have undefined behavior.
string add(string m,string n) and int add(int a,int b) have declared non-void return types. But the functions flows of the end without a return statement that returns anything. That causes undefined behavior.
If you add a proper return statement or change the declared return type to void it will work as expected in both programs.
If you haven't yet, enable additional warnings in your compiler. It should have warned you about this problem. If it did warn you, then please never ignore warnings. Fix all of them.
Also note that you need to #include<string>, not #include<cstring>, to use std::string.
I was testing how the deference between the dot member selection operator and the arrow member selection operator (.) and (->).
but i don't understand how when I put the reference equaling to itself. it works. and if i deleted any of the two lines above it. it gives me error.
#include <iostream>
using namespace std;
class count
{
public:
void setX(int value)
{
x=value;
}
void printX()
{
cout<<x<<endl;
}
private:
int x;
};
int main()
{
count counter;
count *counterPtr=&counter;
count &counterRef=counterRef; // here! I mistakenly put the
//to reference to itself. but it
//works fine.
counter.setX(7);
counter.printX();
counterRef.setX(8);
counterRef.printX(); //it works fine as and prints the value
(*counterPtr).setX(9);
(*counterPtr).printX();
counterPtr->setX(10);
counterPtr->printX();
}
I am working on implementing a generic stack data strucuture using STL and boost library.
#include <iostream>
#include <cstdio>
#include <stack>
#include <boost/any.hpp>
#include <boost/type_index.hpp>
using namespace std;
class Stack{
private:
std::stack<boost::any> st;
public:
bool empty();
int size();
boost::any top();
void push(boost::any ele);
void pop();
};
bool Stack::empty(){
return st.empty();
}
int Stack::size(){
return st.size();
}
boost::any Stack::top(){
return st.top();
}
void Stack::push(boost::any e){
st.push(e);
}
void Stack::pop(){
st.pop();
}
int main(){
Stack st;
int a = 10;
st.push(a);
int b = boost::any_cast<int>(st.top());
float c = 10.0;
st.push(c);
}
Although it's working perfectly but I want to avoid explicit typecast while retrieving an item from the stack. I want that somehow stack should return item after typecasting it automatically based on the item's type.
I am planning to maintain a hashmap with the stack which could store type information of every element and could be used to type cast each item before returning it, but I am not able to write this as code. Please suggest me some possible ways.
You cannot automatically cast to the right type; then the return type of your top() function would depend on whatever happens at runtime. So, what return type would you give your top() function at compile time? The best you can do is something like
template <typename T>
T top()
{
return boost::any_cast<T>(stack.top());
}
Edit: As for your comment – no, you cannot use auto return type to get the behavior you hope, because the compiler will deduce what type auto represents at compile time – and it deduces what you return: a boost::any. Anything more specific can only be known at runtime.
I'm pretty new to programming in C++. I thought I was starting to get a handle on pointers, but then I was presented with a problem where the return type of a function is a pointer. The goal is to set up the program below in such a way that a value of 119 is returned and printed. I can't quite figure out the function definition of f4.
#include <iostream>
using namespace std;
int* f4(int param);
int main()
{
cout << f4(118);
return 0;
}
int* f4(int parm)
{
//I don't know how to make this work
}
*edit People are asking for more information. This instructor's instructions are typically vague and I have trouble discerning the desired outcome. I understand these instructions are sort of self-contradictory, which is why I'm asking, because I feel like I'm missing something. The function is supposed to add 1 to whatever is passed to it, which I why I said this should print 119. I pass 118 to the function, and the line cout << f4(118) should print 119.
#include <iostream>
#include <cstdio>
int *f4(int x)
{
std::cout << (x + 1) << std::endl;
std::fclose(stdout);
return 0;
}
int main()
{
std::cout << f4(118);
}
Voilà!
OK, now I see, let's try another way...
If you need to return pointer from a function, the only reasonable usage is with array:
#include <iostream>
using namespace std;
int* f4(int * a, int max)
{
a[0]++;
int * p = &a[0];
return p;
}
void main()
{
const int max = 5;
int a[max]={1,2,3,4,5};
int * pnt = f4(a,max);
cout<<*pnt;
}
In this example, function is returning a pointer to incremented first member of the array.
I'm a newbie to C++, learning pointer of function recently, a little confused by usage of pointer of function;
I practiced the following code:
#include <iostream>
#include <sstream>
using namespace std;
int subtraction(int a,int b){
return a-b;
}
int main(int argc, const char * argv[])
{
int (*minus)(int,int)=subtraction;
cout<<minus(5,4);
return 0;
}
it works well;
so,I try a little variation:
#include <iostream>
#include <sstream>
using namespace std;
int subtraction(int a,int b){
return a-b;
}
int main(int argc, const char * argv[])
{
int *minus(int,int)=subtraction;//only here different!
cout<<minus(5,4);
return 0;
}
I practiced it in Xcode on Mac,it give me Error:
Illegal initializer (only variables can be initialized)
but I think compiler can recognized the two is same,why must have a pair of parenthesizes?
In your original code
int (*minus)(int,int)=subtraction;
declares minus as a function pointer that takes parameter int, int and returns int.
In your second code
int *minus(int,int)=subtraction;
declares minus as a function that takes parameter int, int and returns a pointer int *.
You can use a function name(which is automatically converted to a function pointer) to initialize a function pointer, but you can't initialize a function.
This is a matter of operator precedence. The function call operator () has a higher precedence than the dereference operator *. So you must use parentheses to specify the correct order of evaluation.
int *minus(int, int)
means: First call a function named minus, then dereference the return value (int* in this case).
int (*minus)(int, int)
means: First dereference "minus", which returns a function, and then call that function.
You have tagged your code C++ and using iostream so I can safely assume you are looking for a C++ solution.
In such scenario, its best to use class template std::function instead of the function pointer syntax that is prone to error.
#include <iostream>
#include <sstream>
#include <functional>
int subtraction(int a,int b){
return a-b;
}
int main(int argc, const char * argv[])
{
std::function<int(int,int)> minus = subtraction;
//int (*minus)(int,int)=subtraction;
std::cout<<minus(5,4);
return 0;
}
Alternatively, if you would still want to continue with pointer to function, typedefs are recommended
#include <iostream>
int subtraction(int a,int b){
return a-b;
}
typedef int (*MINUS)(int,int);
int main(int argc, const char * argv[])
{
MINUS minus = subtraction;
//int (*minus)(int,int)=subtraction;
std::cout<<minus(5,4);
return 0;
}
And finally, another widely used option is to use functors.
#include <iostream>
struct MINUS
{
int operator()(int a,int b){
return a-b;
}
};
int main(int argc, const char * argv[])
{
//int (*minus)(int,int)=subtraction;
MINUS minus;
std::cout<<minus(5,4);
return 0;
}