This question already has answers here:
Where to put default parameter value in C++? [duplicate]
(10 answers)
Default value of function parameter
(5 answers)
Closed 1 year ago.
I want to know how do u declare a function with definite arguments. It's said to be good practice to put the function declaration at the beginning , before the main() function and then its definition, but in this case the compiler gives me an error, becase it's like if it doesn't see the formal arguments.
#include <iostream>
using namespace std;
void function(int i=1, char a='A', float val=45.7);
int main()
{
function();
return 0;
}
void function(int i = 1, char a='A', float val=45.7)
{
cout << "i: " << i << endl;
cout << "a: " << a << endl;
cout << "val: " << val << endl;
}
I tried to insert the formal arguments in the declaration, but it doesn't work.
You can put predefined arguments either in the forward declaration or in the function parameter, but not both
If your function has a forward declaration, you really should only have predefined arguments in the forward declaration, not in the function parameter.
Change that to:
void function(int i, char a, float val)
{
// you shouldn't use using namespace std;
std::cout << "i: " << i << '\n'; // notice the use of newline character instead of std::endl
std::cout << "a: " << a << '\n';
std::cout << "val: " << val << '\n';
}
here is the way to initialise the function args to default values.
You dont need to pass default args in defination. They should be given only in the declaration itself.
#include <iostream>
using namespace std;
void function(int i=1, char a='A', float val=45.7);
int main()
{
function();
return 0;
}
void function(int i, char a, float val)
{
cout << "i: " << i << endl;
cout << "a: " << a << endl;
cout << "val: " << val << endl;
}
Now, this code will work like a charm.
Link to working example -> http://cpp.sh/4j7lx
Related
I'm following simple C++ tutorial.
#include <iostream>
using namespace std;
int main()
{
int a = 1, b = 2;
cout << "Before swapping " << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(a,b);
cout << endl;
cout << "After swapping " << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int &n1, int &n2)
{
int temp;
temp = n1;
n1 = n2;
n2 = temp;
}
The above code works fine (both g++ and icc), but if I were to use pointers in the functions the code fails if I do not include the prototype at the head of the program.
#include <iostream>
using namespace std;
void swap(int*, int*); // The code fails if I comment this line.
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(&a, &b);
cout << endl;
cout << "After swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int* n1, int* n2)
{
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
As far as I know, C++ compiling process is top-bottom, so the 2nd code seems more reasonable in which the information of the function is provided before int main() is encountered. My question is, why the 1st code works fine even without the knowledge of function before int main()?
The issue with the first program is you're not actually calling your own swap function. At the top of the file, you have:
using namespace std;
which brings std::swap into scope and that's the function that you're actually calling. If you put a cout statement in your own swap you'll see that it's never actually called. Alternatively, if you declare your swap before main, you'll get an ambiguous call.
Note that this code is not required to behave like this, since iostream doesn't necessarily bring std::swap into scope, in which case you'll get the error that there is no swap to call.
In the second program, the call to swap(&a, &b) fails because there is no overload of std::swap that accepts 2 temporary pointers. If you declare your swap function before the call in main, then it calls your own function.
The real bug in your code is the using namespace std;. Never do that and you'll avoid issues of this nature.
The reason why the first version works is because it doesn't call your swap(...) function at all. The namespace std provides - Edit: depending on the headers you (and the standard headers themselves) include - swap(...) functions for various types and integers are one of them. If you would remove using namespace std you would have to type std::swap(...) to achieve the same effect (same goes for std::cout, std::endl).
That's one reason why using namespace is a double-edged sword for beginners in my opinion but that's another topic.
Your code is fine; but you're right, it fails if you comment on the line you point to.
But actually, as the others tell you, there is a Swap function in c ++, so it doesn't matter if you create a prototype of the function and do it later because the compiler calls its own swap function.
But since swap works for any data type, except for pointers, then you will understand the reason for your problem, since in this case you do have to create your own swap function that accepts pointers as parameters.
Just move your function above main to make it work correctly, nothing more:
#include <iostream>
using namespace std;
//void swap(int*, int*); // The code fails if I comment this line.
void swap(int* n1, int* n2)
{
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(&a, &b);
cout << endl;
cout << "After swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
I have a case where lookup and overload resolution behaves differently:
for user-defined class vs built-in types vs std::string
for direct call vs function pointer call
I cannot figure what exact parts of the standard justify these differences.
Consider the following C++11 code:
#include <iostream>
#include <string>
using namespace std;
struct Test1 {};
struct Test2 {};
template<typename T>
int f(T t) { return 0; }
int f(Test1 t) { return 10; }
int f(int y) { return 20; }
template<typename T>
int use1() { return f(T()); }
template<typename T>
int use2() { auto fp = static_cast<int(*)(T)>(&f); return (*fp)(T()); }
int f(Test2 t) { return 30; }
int f(string s) { return 40; }
int f(double y) { return 50; }
int main() {
cout << "use1<float>: " << use1<float>() << endl;
cout << "use1<Test1>: " << use1<Test1>() << endl;
cout << "use1<int>: " << use1<int>() << endl;
cout << "use1<Test2>: " << use1<Test2>() << endl;
cout << "use1<string>: " << use1<string>() << endl;
cout << "use1<double>: " << use1<double>() << endl;
cout << endl;
cout << "use2<float>: " << use2<float>() << endl;
cout << "use2<Test1>: " << use2<Test1>() << endl;
cout << "use2<int>: " << use2<int>() << endl;
cout << "use2<Test2>: " << use2<Test2>() << endl;
cout << "use2<string>: " << use2<string>() << endl;
cout << "use2<double>: " << use2<double>() << endl;
return 0;
}
Output is (same with g++ 6.3 and clang++5.0.0 trunk):
use1<float>: 0
use1<Test1>: 10
use1<int>: 20
use1<Test2>: 30
use1<string>: 0
use1<double>: 0
use2<float>: 0
use2<Test1>: 10
use2<int>: 20
use2<Test2>: 0
use2<string>: 0
use2<double>: 0
Questions:
Why use1<string> is different from use1<Test2> ? Both types are declared "at the top", both f() overloads are declared at the bottom.
Why use1<Test2> is different from use1<double>? Corresponding f() overloads are on adjacent lines, is there anything special in treatment of built-in types?
Why use1<Test2> is different from use2<Test2>? The type of a pointer to function in use2 seems to match the calling context in use1.
Two-phase name lookup. At the point where use1 is defined, three overloads of f are visible via normal lookup. At the point of instantiation, additional overloads may be found - but only by argument-dependent lookup. Test2 is in global namespace, so f(Test2) is found by ADL; whereas string is in namespace std, and so f(string) (which is, obviously, not in namespace std) is not found by ADL. double has no associated namespaces, and so ADL doesn't kick in at all.
In use2, f is not a dependent name, and so the second-phase lookup is not performed at all - only overloads visible at the point of definition are considered.
Good evening, I'm attempting to call my void function "getProblems" in main, but get an extraneous value when outputting "getProblems" with no parameters. Similarly, when passing arguments, such as "getProblems(list, i)", I get the error "no operator '<<' matches these operands". The goal is to output the number of problems my text file contains without using a function that returns a value or using pointers.
#include<iostream>
#include<iomanip>
#include<string>
#include<fstream>
using namespace std;
int const MAX_PROBLEMS = 50;
void getProblems(string problem[], int& count);
int main()
{
string list[MAX_PROBLEMS] = {};
int i = 0;
cout << "There are " << getProblems << " problems. " << endl;
// I have also tried calling the void function with parameters
// cout << "There are " << getProblems(list, i) << "problems. " << endl;
return 0;
}
void getProblems(string problem[], int& count)
{
ifstream mathProblems;
mathProblems.open("P4Problems.txt");
if (!mathProblems)
{
cout <<"No file was found."<< endl;
}
count = 0;
string data;
getline(mathProblems, data);
while (!mathProblems.eof())
{
problem[count] = data;
count ++;
mathProblems >> data;
}
mathProblems.close();
}
Your function getProblems() is of type void, so what are you trying to display with cout?
If you need to display the count, which is an argument,
int main()
{
int count;
getProblems(listt,count); //assuming listt, has been declared before
cout << "There are " << count << " problems. " << endl;
return 0;
}
#include <iostream>
using namespace std;
void swap(int, int);
int main()
{
int a=10;
int b=20;
swap (a, b);
cout << "a: " << a << endl;
cout << "b: " << b << endl;
return 0;
}
void swap(int x, int y)
{
int t;
t = x;
x = y;
y = t;
}
those code above can't swap the value of a and b.
but my question is , when I forgot to type the third line "void swap(int, int);
" , the values of a and b swaped !! why?
It's because you have
using namespace std;
At the beginning of your source code.
This is a a bad programming practice, whose consequences you just experienced, first hand. You told the compiler that you want to invoke std::swap, without having any clue that you actually did that.
It's ironical, because you version of swap() won't work right, but std::swap does; so you were operating under the mistaken impression that your code was working, when it didn't.
Never use "using namespace std;" with your code. Simply forget that this part of the C++ language ever existed.
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int b = 20;
cout << "a: " << a << endl;
cout << "b: " << b << endl;
system("pause");
swap(a, b);
cout << "a: " << a << endl;
cout << "b: " << b << endl;
system("pause");
return 0;
}
void swap is unnecessary
If you put the function definition above main then you don't need a prototype otherwise you do need it and the compiler should give you an error if you don't have a prototype
I'm trying to make something in C++ and I have a problem. I have this code:
#include <iostream>
#include <string>
//---MAIN---
using namespace std;
int af1 = 1;
int af2 = 1;
void lettersort(int cnt1) {
cout << "RESULT:" << cnt1 << endl;
cnt1++;
cout << "RESULT WHEN+:" << cnt1 << endl;
cout << "RESULT IN GLOBAL INT:" << af2 << endl;
}
int main()
{
lettersort(af2);
return 0;
}
So is there any way so that cnt1++ affects af2 too, to make it bigger ? I don't want to use af2++ directly because I want to sometimes use af1.
At the moment you are just passing af2 to cnt1 by value, so any changes to cnt1 are strictly local to the function lettersort. In order to get the behaviour you want you need to pass your cnt1 parameter by reference. Change:
void lettersort(int cnt1)
to:
void lettersort(int &cnt1)
You are passing the argument by value. I.e., you are copying the value of af1 to a local variable in lettersort. This integer is then incremented, and disposed of when the function ends, without affecting the original af1. If you want the function to be able to affect af1, you should pass the argument by reference:
void lettersort(int& cnt1) { // Note the "&"
if i understood your question:
there are 2 ways you can do that.
make lettersort function return the new value, and put it in af2
int lettersort(int cnt1) {
cout << "RESULT:" << cnt1 << endl;
cnt1++;
cout << "RESULT WHEN+:" << cnt1 << endl;
cout << "RESULT IN GLOBAL INT:" << af2 << endl;
return cnt1;
}
int main()
{
af2 = lettersort(af2);
return 0;
}
pass the value by reference. you can read about it here, but generally its about passing a pointer to that value. meaning whatever you do on the argument you are passing, will happen on the original var.
example:
void foo(int &y) // y is now a reference
{
using namespace std;
cout << "y = " << y << endl;
y = 6;
cout << "y = " << y << endl;
} // y is destroyed here
int main()
{
int x = 5;
cout << "x = " << x << endl;
foo(x);
cout << "x = " << x << endl;
return 0;
}
here you have to just modified the argument pass to lettersort
function as passed by reference.
for example if you declare and initialize any variable like:
int a=10; int &b = a;
now a and b refer to the same value.if you change a then the changes
also reflect in b also.
so,
cout << a; cout << b;
both statement produce the same result across the program. so using
this concept i modified the function argument and made it as by
reference.
your correct code is :
#include <iostream>
#include <string>
using namespace std;
int af1 = 1;
int af2 = 1;
void lettersort(int &cnt1) {
cout << "RESULT:" << cnt1 << endl;
cnt1++;
cout << "RESULT WHEN+:" << cnt1 << endl;
cout << "RESULT IN GLOBAL INT:" << af2 << endl;
}
int main()
{
lettersort(af2);
return 0;
}