Inbuilt __gcd(A,B) function in C++ - c++

recently I get to know about a special function in c++ : __gcd(A,B). this will return the greatest common divisor of A and B.
#include<iostream>
#include<algorithm>
using namespace std;
main()
{
cout<<__gcd(10,40); //op: 10
}
is there any special reason for starting function definition with 2 underscores?
It could be as simple as gcd(A,B) like other STL functions.

Names starting with two underscores are reserved for the implementation, which means that you are not allowed to define such names in your code, and there are no standard guarantees what those names mean if they do exist. However, a vendor might choose to document some such names, in which case you can use them with the product for which the vendor documents them.

In C++17 there are standard library functions for GCD and LCM.
#include <iostream>
#include <numeric>
int main ()
{
int a, b;
std::cin >> a >> b;
std::cout << std::gcd(a,b) << '\n';
return (0);
}

Related

Can I use a std::string variable as an argument to an operator?

For example, if I have:
#include <iostream>
using namespace std;
int main()
{
int b = 1;
int c = 2;
string a = "(b + c)";
cout << (4 * a) << "\n";
return 0;
}
Is it possible to have string a interpreted literally as if the code had said cout << (4 * (b + c)) << "\n";?
No. C++ is not (designed to be) an interpreted language.
Although it's theoretically possible to override operators for different types, it's very non-recommended to override operators that don't involve your own types. Defining an operator overload for std::string from the standard library may break in future. It's just a bad idea.
But, let's say you used a custom type. You could write a program that interprets the text string as a arithmetic expression. The core of such program would be a parser. It would be certainly possible, but the standard library doesn't provide such parser for you.
Furthermore, such parser wouldn't be able to make connection between the "b" in the text, and the variable b. At the point when the program is running, it has no knowledge of variable names that had been used to compile the program. You would have to specify such information using some form of data structure.
P.S. You forgot to include the header that defines std::string.
#include<string>
///...
auto a=std::to_string(b+c);
std::cout<<4*std::stoi(a)<<std::endl;
You can just use std::string and std::stoi.

c++ implicit type conversion string -> int?

I was just working on c++ types, when i just thought of trying out the following program.
void swap(int& a, int& b){
int temp = a;
a = b;
b = temp;
}
int main(){
string a{"sssss"}, b{"ddddd"};
swap(a,b); //this should not work!! but it does
cout << a << ' '<<b <<endl;
return 0;
}
I was not expecting this to swap the strings, but it does! Why is this working? Although the compiler raises warnings, it is not an error!
Your program does not compile. I am guessing that you actually had the following lines but failed to post them:
#include <iostream>
#include <string>
using namespace std;
There is a standard template std::swap. Although this is in #include <algorithm>, any header may include any other header. So even if you didn't include this specifically, it may have gotten included anyway.
So when you call an unqualified swap, both your swap and std::swap are included in overload resolution. (Even if you didn't have using namespace std;, namespace std is still searched because of ADL, since the arguments are of type std::string which is in namespace std).
To avoid this happening, you could put your swap in a named namespace, and use the qualified name (e.g. mystuff::swap(a, b);).
// Assuming the following:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
// or even using namespace std, though this
// would make std::swap a candidate even
// without ADL
// renaming shows that it's not this function
// that gets called ...
void myswap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
// printing some output also reveals what's going on
}
int main() {
string a{"sssss"}, b{"ddddd"};
swap(a,b); // this is not calling your swap!
// myswap(a,b) produces the error you expected
cout << a << ' '<< b <<endl;
return 0;
}
It's not calling your swap function. Namespaces are kind of interfaces, so when one declares free functions to be in the same namespace as the data types they operate on, then calling them without proper namespace qualification will work.
This is called "argument dependent name lookup", or ADL.
So when you call the function swap on a std::string, it'll also look for candidates in the std namespace. And since there's std::swap, which can be applied to strings and no other candidate in your global namespace (since your swap only operates on integers) it'll use it for the call.
As I showed above you can make your function produce debugging output or rename it to easily verify that it's not your function that is called.
As a side note: Suppose there were some kind of implicit conversion from string to int. You'd then get two temporaries. Then your swap function would get called (not in reality, since binding non const references to temporaries isn't allowed) and these integers exchanged. And then? This wouldn't have any effect on the original strings.
Finally, I wouldn't count this code as portable. It only compiles when either the header string or iostream includes the algorithm header, and one of these three provides the specialisation of std::swap for strings. But since this doesn't seem to be guaranteed by the standard, this code would only reliably work when including algorithm yourself.

Implicit casting acting strange

I have a question about implicit casting for the following code
#include <iostream>
using namespace std;
float max(int a, int b)
{
if (a > b)
return a;
else return b;
}
int main() {
double a, b;
cin >> a >> b;
cout << max(a, b)<<endl;
cout << a;
return 0;
}
Now Supposing that a = 30.5 & b = 26.4.
The anticipated result is 30 however on one computer(MinGW & VS 2005) I get 30.5.
Does anyone have an interpretation for this ? It makes no sense to me.
Edit 1 :
on third line output is 30.5 instead of the anticipated 30
Solution
std::max() is shadowing it, but why it shadows it on one computer and it doesn't on another I didn't investigate in that.
So try to avoid naming your functions or classes with names reserved for the standard library.
This is whats resulting in the weird output:
using namespace std;
When calling max() you may be calling std::max() which may be included in <iostream> with no guarantees. Try this:
cout << ::max(a, b)<<endl; //forces global scope
Should print out 30.

Template class in c++?

I am using a template class to set the data type for a swap function. In the code if i initialize the function name as lower case letter it throws an error
call of overloaded 'swap(double&, double&) is ambiguous
but when i initialize the function name as upper case it works fine.
Will appreciate if someone could explain me why this is happening. Here is my code
#include<iostream>
using namespace std;
template <class T>
void swap(T &a,T &b)
{
T temp;
temp = a;
a = b;
b = temp;
}
int main()
{
double value1 = 2.44;
double value2 = 6.66;
cout<<"\tBefore swap \n";
cout<<"Value 1 = "<< value1 <<"\tValue 2 = " << value2 <<"\n";
swap(value1,value2);
cout<<"\tafter swap \n";
cout<<"Value 1 = "<< value1 <<"\tValue 2 = "<<value2;
}
Instead of
swap(value1,value2);
use
::swap(value1,value2);
This would solve the namespace and ambiguity issue.
because there is already a standard library function std::swap http://www.cplusplus.com/reference/algorithm/swap/ so possibly your compiler does not like it? You pull that in via using namespace std;
Change the name of your swap function because std::swap already exists.
Or you could put it in a separate namespace and use the scope resolution operator, "::", to distinguish yours from the standard one.
This is what happens when you use namespace std;. You may want to be more specific and use:
using std::cout;
using std::endl;
using std::cin;
Already standard library function is defined with templates 'swap' Instead of 'SWAP',It is actually under the std namespace, but because you have a using namespace std line, it exists without the std:: prefix.
As you can see, using the using namespace std isn't always a good option because of possible name collisions, as in this example. In general one should prefer not to use the using directive unless there's a real reason for this - namespaces exist for a reason - to prevent name collisions.

Why does this program swap the values?

I have the following code:
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <conio.h>
#include <cstring>
#include <iomanip>
void swap(long a, long b)
{
long temp;
temp=a;
a=b;
b=temp;
}
int _tmain(int argc, _TCHAR* argv[])
{
int x = 5, y = 3;
cout << x ;
cout << y << endl;
swap(x, y);
cout << x ;
cout << y << endl;
getch();
return 0;
}
The program gives the output:
5 3
3 5
The program actually swaps the values! Why is that? The parameters of the swap() are not pointers or references.
(I am using VS 2005)
Your swap function isn't being called at all.
One of the Standard Library includes that you have included is pulling in <utility>, which declares a function template named swap in the std namespace. Since you are using namespace std;, that swap function is being brought into the global namespace and it is called instead.
Why is std::swap chosen instead of your swap function? Your swap function takes two longs by value; to call that function, an integer promotion is required for each of the int arguments.
std::swap is a function template. It takes two references to T, and when that function template is instantiated with T = int, both arguments are an exact match. So, std::swap is a better match than your function and it is therefore selected during overload resolution.
This is one reason that using namespace std; is evil and should be avoided. If you remove the using directive, your function will be the only function available and it will be called.
Say long instead of int.
Your current code already has a better match for swap, so it avoids the implicit conversion to long, and instead uses the built-in swap from the STL.
On a side note, this ambiguity is somewhat solved using overload sets (also here) in the language D.