Why does the following code always prints "type is double"? (I have seen this code in StackOverflow)
#include <iostream>
void show_type(...) {
std::cout << "type is not double\n";
}
void show_type(double value) {
std::cout << "type is double\n";
}
int main() {
int x = 10;
double y = 10.3;
show_type(x);
show_type(10);
show_type(10.3);
show_type(y);
return 0;
}
http://en.cppreference.com/w/cpp/language/overload_resolution says:
A standard conversion sequence is always better than a user-defined conversion sequence or an ellipsis conversion sequence.
void show_type(double value) {
std::cout << "type is double\n";
}
if u comment above line then output will be
type is not double
type is not double
type is not double
type is not double
it means that compile always prefer the void show_type(double value) over void show_type(...).
in your case if you want call the method void show_type(...) pass the two or more arguments when u calling this method show_type(firstParameter,secondParameter)
#include <iostream>
void show_type(...) {
std::cout << "type is not double\n";
}
void show_type(double value) {
std::cout << "type is double\n";
}
int main() {
int x = 10;
double y = 10.3;
show_type(x);
show_type(10);
show_type(10.3);
show_type(y);
show_type(4.0,5); //will called this method show-type(...)
return 0;
}
now the output of above line will be
type is double
type is double
type is double
type is double
type is not double //notice the output here
more info on var-args
Related
I want a function that can accept any type of argument and then in the implementation, can check if the type is integer and then can throw a message. For example the function can be called like the following,
add(10, 12);
Output : "correct input. addition is 22"
add(10, "hello")
Output : "wrong input"
add(10)
Output : "wrong input! missing arguments"
Is it possible to achieve this in C++?
Using overloading I will have to create functions of all possible combination such as (int, double), (double, int), (int, string), (string, int) and so on, so is there any other way?
Since C++17, you can use std::any and std::any_cast:
#include <any>
#include <iostream>
void add(const std::any& a = "", const std::any& b = "")
{
try {
const int ia = std::any_cast<int>(a);
const int ib = std::any_cast<int>(b);
std::cout << "correct input. addition is " << ia + ib << std::endl;
}
catch (...) {
std::cout << "wrong input" << std::endl;
}
}
int main()
{
add(10, "hello");
add(10, 12);
add(10);
add();
}
Demo
A pre-C++17 solution:
#include <iostream>
void add(int a, int b)
{
std::cout << "correct input. addition is " << a + b << std::endl;
}
template<typename... Ts>
void add(Ts...)
{
std::cout << "wrong input" << std::endl;
}
int main()
{
add(10, "hello");
add(10, 12);
add(10);
add();
}
Demo
The first thing to do is write an overload that accepts exactly 2 ints:
void add(int a, int b) {
std::cout << "Correct input. Answer is " << a + b << "\n";
}
And that should generally be enough. If a call is made with an incorrect number of arguments, or with 2 arguments that can't be converted to int, the compiler will produce an error for you.
If you don't want an error, but instead want to print an error message at runtime, you can just add overloads. As you've noticed, adding overloads for explicit types isn't really going to work, but you can add a generic function (a function template) that will accept anything:
void add(auto ...) {
std::cout << "Incorrect input\n";
}
Note that pre-C++20, the signature has to be spelled
template<typename ...Ts>
void add(Ts ...);
You can continue adding more overloads if you want more specific error messages, e.g. for a call where only one argument is passed:
void add(auto) {
std::cout << "Insufficient arguments\n";
}
Here's a demo.
I am a new C++ programmer. I am creating a calculator, and I have a problem with my void printAnswer() function. Whenever I call the function and I type in the parameter (which is a double variable), the function name always turns into a variable identifier. When I compile, it says
Severity Code Description Project File Line Suppression State
Error (active) E0070 incomplete type is not allowed Calculator C:\Users\jk\Downloads\Coding Stuff\Calculator\Calculator.cpp 17
Error C2182 'printAnswer': illegal use of type 'void' Calculator C:\Users\jk\Downloads\Coding Stuff\Calculator\Calculator.cpp 17
Warning C4244 'initializing': conversion from 'double' to 'int', possible loss of data Calculator C:\Users\jk\Downloads\Coding Stuff\Calculator\Calculator.cpp 17
This is my header file.
#ifndef CALCULATOR_H
#define CALCULATOR_H
void calculator();
double getValue1(double);
double getValue2(double);
std::string getOperation(std::string);
double calculation(double, double, std::string);
void printAnswer(double);
#endif
This is my main file
#include <iostream>
#include <string>
#include "Calculator.h"
int main()
{
double a{};
double b{};
double x{ getValue1(a) };
std::string calculatorOperation{};
std::string operation{ getOperation(calculatorOperation) };
double y{ getValue2(b) };
double answer{ calculation( x, y, operation ) };
void printAnswer(answer);
/*
* if (answer == 99999999999999999.999)
* std::cout << "Sorry. The desired operation does not exist or you have misspelled
somthing.\n";
* else
* std::cout << "The answer is " << answer << ".\n";
*
* return 0;
*/
}
double getValue1(double x)
{
std::cout << "Please type your first number and press enter.\n";
std::cin >> x;
return x;
}
double getValue2(double y)
{
std::cout << "Please type your second number and press enter.\n";
std::cin >> y;
return y;
}
std::string getOperation(std::string operation)
{
std::cout << "Please type in the desired operation in all undercase and press enter.\n";
std::cin >> operation;
return operation;
}
double calculation(double x, double y, std::string operation)
{
if (operation == "addition")
return x + y;
else if (operation == "subtraction")
return x - y;
else if (operation == "multiplication")
return x * y;
else if (operation == "division")
return x / y;
else
return 99999999999999999.999;
}
void printAnswer(double answer)
{
if (answer == 99999999999999999.999)
std::cout << "Sorry. The desired operation does not exist or you have misspelled somthing.\n";
else
std::cout << "The answer is " << answer << ".\n";
}
In your main function, you have this line:
void printAnswer(answer);
Here the compiler thinks that you are trying to declare a void variable named printAnswer which is constructed from the value answer. The compiler gives an error since you can't create a void variable.
It seems you want to call the function printAnswer with the argument answer. The correct syntax for that is:
printAnswer(answer);
I wrote this code to check the exceptions I learned in a video, and now I tried to make the cube of an integer and if the entered number is not an integer I want the exception to be announced to the user.
#include <iostream>
float cube( float x)
{
char ch;
std::cin.get(ch);
if(ch=='.')
throw "Should be an integrer";
float cube=x*x*x;
return cube;
}
int main ()
{
float x;
std::cout<<" Enter an integrer : ";
std::cin>>x;
float cube_x=cube(x);
std::cout<<"Cube("<<x<<")="<<cube_x<<std::endl;
return 0;
}
You can use boost lexical-cast which is exactly for this purpose. It will throw an exception the conversion fails. Boost is well tested and you can safly use it to do the conversion for you.
This could look like this:
#include <boost/lexical_cast.hpp>
#include <iostream>
int cube(int x)
{
return x*x*x;
}
int main()
{
std::string x;
std::cout << " Enter an integrer : ";
std::cin >> x;
try
{
int y = boost::lexical_cast<int>(x);
int cube_x = cube(y);
std::cout << "Cube(" << x << ")=" << cube_x << std::endl;
}
catch (const boost::bad_lexical_cast &e)
{
std::cerr << e.what() << '\n';
}
return 0;
}
By the way, if your program shall only handle integers, you should also use type int and not float to handle the numbers.
Add the following to your source code:
#include <math.h> /* round, floor, ceil, trunc */
...
if (x == round(x)) {
...
}
Explanation can be found here: C++ Reference
The task is to create class, which counts the objects of its type, in every moment. Here is my code. The errors are:
1. the object has type qualifiers that are not compatible with the member function "counter::print";
2. return value type does not match the function type; - this was obwious really!
I corrected the errors and it gives me new one that I can't fix;
1. 'void counter::print(void)': cannot convert 'this' pointer from 'const counter' to 'counter &'
class counter {
private:
static int count;
public:
counter();
counter(const counter &from);
void print() const;
~counter();
};
counter::counter() {
++count;
}
counter::counter(const counter &from) {
++count;
cout << "Copy constructor:\t";
from.print(); // here is the error
}
void counter::print() const{
cout << "\t Number of objects = " << count << endl;
}
counter::~counter() {
--count;
cout << "Destructor:\t\t";
print();
}
int counter::count = 0;
counter f(counter x);
void main() {
counter c;
cout << "After constructing of c:";
c.print();
cout << "Calling f()" << endl;
f(c);
cout << "After calling f():";
c.print();
}
counter f(counter x) {
cout << "Argument inside f():\t";
x.print();
return x;
}
Firstly, change:
void print();
to:
void print() const;
because (a) it's a const method anyway and (b) you're trying to call it in a const context within your constructor.
For the second error here:
void f(counter x) {
cout << "Argument inside f():\t";
x.print();
return x; // 2 - nd error
}
it should be fairly obvious that you can't return a value from a void function. Either change it to:
counter f(counter x) {
cout << "Argument inside f():\t";
x.print();
return x;
}
or simply don't return anything:
void f(counter x) {
cout << "Argument inside f():\t";
x.print();
}
void print();
You have declared a non-const member function, which means it cannot be called by const instances.
from.print(); // 1 - st error
Here the type of from is const counter& which means it cannot call the print function. Instead make your print function const.
void print() const;
void counter::print() const { ... }
return x; // 2 - nd error
Why are you returning anything from a function with a void return type?
I want to implement a function like this
double d = string_to("1223.23",double);
int i = string_to("1223",int);
bool d = string_to("1",bool);
How can I pass the bool, int, double data type to implement this in c++?
Types line int, double and bool can only be passed as template parameters.
You can use templates like this:
#include <string>
#include <sstream>
#include <iostream>
template<typename DataType>
DataType string_to(const std::string& s)
{
DataType d;
std::istringstream(s) >> d; // convert string to DataType
return d;
}
int main()
{
double d = string_to<double>("1223.23");
int i = string_to<int>("1223");
bool b = string_to<bool>("1");
std::cout << "d: " << d << '\n';
std::cout << "i: " << i << '\n';
std::cout << "b: " << b << '\n';
}
As an alternative you can pass your numeric types by reference and rely on function overloading to select the correct function:
void string_to(const std::string& s, double& d)
{
d = std::stod(s);
}
void string_to(const std::string& s, int& i)
{
i = std::stoi(s);
}
void string_to(const std::string& s, bool& b)
{
std::istringstream(s) >> std::boolalpha >> b;
}
int main()
{
double d;
int i;
bool b;
string_to("1223.23", d);
string_to("1223", i);
string_to("true", b);
std::cout << "d: " << d << '\n';
std::cout << "i: " << i << '\n';
std::cout << "b: " << b << '\n';
}
Also you could templatize the second method (an exercise for the reader).
If you really want to do this, you can pass the type by using the typeid operator.
E.g. double d = string_to("1223.23", typeid(double));
Using the library functions atoi, stod would make more sense.
If you're aiming to write more uniform code then you could write a Converter object and use method overloading to get automatic selection by type.
class Converter
{
public:
void fromString(double& value, const char* string);
void fromString(int& value, const char* string);
void fromString(long& value, const char* string);
};
Here's another way that uses tag dispatching. You can compile and run this example.
#include <iostream>
#include <string>
#include <cmath>
namespace detail {
// declare the concept of conversion from a string to something
template<class To>
To string_to(const std::string&);
// make some models of the concept
template<>
int string_to<int>(const std::string& s) {
return atoi(s.c_str());
}
template<>
double string_to<double>(const std::string& s) {
return atof(s.c_str());
}
template<>
std::string string_to<std::string>(const std::string& s) {
return s;
}
// ... add more models here
}
// define the general case of conversion from string with a model tag
// note the unused parameter allows provision of a model that is never used
// thus the model will in all likelihood be optimised away
template<class To>
To string_to(const std::string& from, const To& /* model_tag is unused */)
{
// dispatch to correct conversion function using the To type
// as a dispatch tag type
return detail::string_to<To>(from);
}
using namespace std;
int main()
{
// examples
int a = string_to("100", a);
double b = string_to("99.9", b);
const string s = string_to("Hello", s);
cout << s << " " << a << " " << b << endl;
return 0;
}
output:
Hello 100 99.9