This question already has answers here:
Warnings or errors for C++ implicit conversion of primitives
(6 answers)
Closed 5 years ago.
I am using the following sample program in C++
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
namespace mine{
template<class T>
inline void swap(T &a, T &b){
char c= a; //This should not have compiled
a=b;
b=c;
}
}
int main(){
int a,b;
cout<< "Enter two values: ";
cin>>a>>b;
mine::swap(a,b); //type variable T is instantiated as in
cout << a <<' '<<b << endl;
}
I am expecting the compiler to throw an error in the swap function, because c is declared as a char, but assigned a variable of generic type variable T. Not only that, when invoking swap, T is instantiated as int. However, not only is g++ not giving any error, the program works perfectly. Why is this the case?
C++ gives you the ability to shoot yourself in the foot.
The fact remains that any integral type is convertible to a char with implementation defined behaviour.
The compiler is assuming you know what you are doing, that's all.
auto c = a; would be the best replacement these days. Prior to C++11 you could have written T C = a; (you still can of course.) Although since C++11 you ought to use std::move when swapping, see how std::swap is implemented on your platform. (Reference How does the standard library implement std::swap?)
gcc will warn you of this if you specify -Wconversion on the command line.
First of all, converting int to char is legal, it is a narrowing conversion, and the compiler might warn you if you configure it to do so.
As for why the code compiles, this is due to the fact that the type is known at compile time, therefore the compiler knows that for all the instances of T that it initialised, T is convertible to char.
If you will change a to a type that is not convertible to char, the compiler will complain: e.g with MSVC
The following code give error C2440: 'initializing' : cannot convert from 'std::string' to 'char':
#include "stdafx.h"
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
namespace mine{
template<class T>
inline void swap(T &a, T &b){
char c= a; //This should not have compiled
a=b;
b=c;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
string a("test");
string b("test2");
mine::swap(a,b); //type variable T is instantiated as in
}
Related
i keep getting this error. i know this is a c++ 11 function but it still isnt working with code blocks c++ compiler. am i using this function correctly of is it a problem with the codeblocks compiler. i tried changing the compiler. using the "have g++ follow the c++11 iso standard" i still keep getting this error. or getting the "stoi() does not exist in the current scope" error
#include <iostream>
#include <string>
using namespace std;
int main()
{
int test = 34;
cout << stoi(test);
}
stoi means "String To Int". It will read an int from a std::string (or std::wstring). See also the reference.
You were probably looking for the reverse std::to_string (reference). But you don't need either, there is no need to convert to string before printing:
#include <iostream>
int main()
{
int test = 34;
std::cout << test;
}
stoi means string to int. So it takes a string as an input.
This should work:
string test = "34"; cout << stoi(test);
Whats the problem with the code below, and why I'm getting this error?
#include <iostream>
#define A 1
using namespace std;
int main()
{
cout <<A++;
return 0;
}
#define A 1 doesn't make a variable called A.
It tells your computer to replace all utterances of A with 1 before compiling.
So, your program is actually:
#include <iostream>
using namespace std;
int main()
{
cout <<1++;
return 0;
}
And you cannot increment the literal 1.
You may read more about preprocessor directives in your C++ book.
#define A 1
A is not valid c++ left value, so gave us "lvalue required as increment operand"
int A;
is valid c++ left value and will work, also of other simple number type float, unsigned char etc
Visual Studio is going crazy on me recently, and gives me the error in the subject when all I did was a simple cout...
CODE:
// Lang.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main{
cout << "hi";
}
int main{
cout << "hi";
}
Due to the possibility of initialising objects in C++ with the {} syntax, your compiler probably interprets this code as an attempt to create a global int variable called main, initialised with the result of std::ostream::operator<<, a member function which returns a reference to the std::ostream itself.
It's as if you had written:
double some_variable { cout << "hi" }
Or:
double some_variable { cout }
std::ostream is actually std::basic_ostream<char, std::char_traits<char>>. And that type is not compatible with int.
The only thing which is strange is why the ; after "hi" does not immediately cause the compiler to stop trying; but you don't say which compiler version and which options you are using.
In any case, all of those facts finally result in the error message:
no suitable conversion function from “std::basic_ostream<char,
std::char_traits<char>>” to “int” exists
and in:
Also, the semicolon after "hi" is highlighted, and says "expected a }"
Solution: make main a function:
int main() {
cout << "hi";
}
This question already has answers here:
call of overloaded 'min(int&, int&)' is ambiguous
(5 answers)
Closed 6 years ago.
#include<conio.h>
#include<iostream>
using namespace std;
template<class T>
T min(T a,T b)
{
return (a>b)?a:b;
}
int main()
{
int x,y;
cin>>x>>y;
cout<<"min. of integer value is="<<min(x,y); //error is call of overloaded function is ambiguous.
float p,q;
cin>>p>>q;
cout<<"min. of floating value is="<<min(p,q);//same error as above
char c1,c2;
cin>>c1>>c2;
cout<<"min. of c1 and c2(basis of ASCII values)="<<min(c1,c2);// same error as above
getch();
return 0; }
Is there any inbuilt feature of dev c++ that doesnt support templates or is there some other error?
The reason is there is a std::min, which gets imported into the global namespace (due to the using namespace std;).
So you have 2 different versions of min: Your version (which actually returns the maximum...), and the standard min.
Either rename your min-function, or remove it (and use std::min instead).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ compiler error: ambiguous call to overloaded function
just copied some code from a pdf into both C++builder XE2 and visual studio express 2012. both both compilers give error codes about ambiquity. I just started so i don't really know what to do. Maybe my textbook(pdf) is old and obsolete now? it's called "Learn c++ in 14 days". Well anyways here is the copied code.
#include <iostream.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>
#pragma hdrstop
void getSqrRoot(char* buff, int x);
int main(int argc, char** argv)
{
int x;
char buff[30];
cout << “Enter a number: “;
cin >> x;
getSqrRoot(buff, x);
cout << buff;
getch();
}
void getSqrRoot(char* buff, int x)
{
sprintf(buff, “The sqaure root is: %f”, sqrt(x));
}
the errorcode i got in c++builder is:
[BCC32 Error] SquareRoot.cpp(19): E2015 Ambiguity between 'std::sqrt(float) at c:\program files (x86)\embarcadero\rad studio\9.0\include\windows\crtl\math.h:266' and 'std::sqrt(long double) at c:\program files (x86)\embarcadero\rad studio\9.0\include\windows\crtl\math.h:302'
Full parser context
SquareRoot.cpp(18): parsing: void getSqrRoot(char *,int)
On a side note, the quotation marks in my pdf manual are different characters than the normal " which i type. these “ are also not compatible with the compiler. maybe anybody knows a fix for this as well? thanks in advance.
Change your code like that:
void getSqrRoot(char* buff, int x)
{
sprintf(buff, “The sqaure root is: %f”, sqrt((float)x));
}
Because square root is overloaded function compiler has no opportunity to implicit conversion from int x value to float or double value, you need to do it directly.
Compiler: see sqrt(int) -> what to choose? sqrt(float)/sqrt(double) ?
Compiler: see sqrt((float)int) -> sqrt(float), ok!
Compeler: see sqrt((double)int) -> sqrt(double), ok!
Change your getSqrRoot Function to the below
void getSqrRoot(char* buff, float x)
{
And similarly fix the declaration in the first line.
This is happening because std::sqrt which is the function you are using to get the square root, can take either a float or a double but you have given it an int which leads to the confusion since the compiler now has no idea which function to call.