How to apply different instantiations to the same name of object? - c++

int lim;
do{
cin>>lim;
switch(lim)
{
case 1: {mpa<1,int,const char*> C; }break;
case 2: {mpa<2,int,const char*> C; }break;
case 3: {mpa<3,int,const char*> C; }break;
case 4: {mpa<4,int,const char*> C; }break;
case 5: {mpa<5,int,const char*> C; }break;
default: cout<<"Incorrect number, please repeat\n";
}
}while(lim<1 || lim>5);
I want to pass a value(1,2,3,4 or 5) to the template int a,typename T1,typename T2. I need different instantiations of this template. But object C will be destroyed after switch. How to apply different instantiations to the same name of object?

In this case, I think the best option is to rethink class mpa to not require that first parameter at compile time. Seriously, everyone hates rewriting things, but that's what you should do.
Since I know you'll ignore that, here's a workaround:
Make a class mpa_base<class, class>, that mpa inherits from, and has all the same functions, but they're all virtual (ESPECIALLY the destructor). Then, you can do this:
typedef mpa_base<int, const char*> mpa_int_pchar;
std::unique_ptr<mpa_int_pchar> C; //this is a smart pointer to a mpa object
int lim;
do{
cin>>lim;
switch(lim)
{
case 1: C.reset(new mpa<1,int,const char*>()); break;
case 2: C.reset(new mpa<2,int,const char*>()); break;
case 3: C.reset(new mpa<3,int,const char*>()); break;
case 4: C.reset(new mpa<4,int,const char*>()); break;
case 5: C.reset(new mpa<5,int,const char*>()); break;
default: cout<<"Incorrect number, please repeat\n";
}
}while(lim<1 || lim>5);

Refactor the common part in another function and then you can easily do this. Also, always have the input from the stream as part of the loop check or make it a break-condition.
template<class MPA>
void foo(MPA const& mpa){
// whatever you want to do, do it here
}
int lim = 0;
do{
if(!(cin >> lim)){ // broken input
cin.clear(); // clear error flags
break; // bail out
}
switch(lim)
{
case 1: { foo(mpa<1, int, char const*>(/*params*/)); }break;
case 2: { foo(mpa<2, int, char const*>(/*params*/)); }break;
case 3: { foo(mpa<3, int, char const*>(/*params*/)); }break;
case 4: { foo(mpa<4, int, char const*>(/*params*/)); }break;
case 5: { foo(mpa<5, int, char const*>(/*params*/)); }break;
default: cout<<"Incorrect number, please repeat\n";
}
}while(lim < 1 || lim > 5);

Related

How to build the simple change maker for a vending machine?

On the menu deposits n,d, q, o,f are indicated which are indication for nickel dime quarter , one dollar and five dollar. I should also indicate "C" as in cancel option when the user hits c. But i couldn't make it work. My program still runs even the user hit c. I am confused on this point?
switch(DepositIndication) {
case 'n': {
PurchasedPrice=PurchasedPrice-0.05;
NumOfNickels=NumOfNickels+1;
}
break;
case 'd': {
PurchasedPrice=PurchasedPrice-0.10;
NumOfdimes=NumOfdimes+1;
}
break;
case 'q': {
PurchasedPrice=PurchasedPrice-0.25;
NumOfquarters=NumOfquarters+1;
}
break;
case 'o': {
PurchasedPrice=PurchasedPrice-1.00;
NumOfOnes=NumOfOnes+1;
}
break;
case 'f': {
PurchasedPrice=PurchasedPrice-5.00;
NumOfFives=NumOfFives+1;
}
break;
}
the condition c is missing and I Put the break into to brackets;
switch (DepositIndication) {
case 'n':
{
PurchasedPrice = PurchasedPrice - 0.05;
NumOfNickels = NumOfNickels + 1;
break;
}
case 'd':
{
PurchasedPrice = PurchasedPrice - 0.10;
NumOfdimes = NumOfdimes + 1;
break;
}
case 'q':
{
PurchasedPrice = PurchasedPrice - 0.25;
NumOfquarters = NumOfquarters + 1;
break;
}
case 'o':
{
PurchasedPrice = PurchasedPrice - 1.00;
NumOfOnes = NumOfOnes + 1;
break;
}
case 'f':
{
PurchasedPrice = PurchasedPrice - 5.00;
NumOfFives = NumOfFives + 1;
break;
}
case 'c':
}
//you can print cancellation messages in here
break;
}
default:
break;
}
I should also indicate "C" as in cancel option when the user hits c
Your current code works fine the only thing you are missing to make that work right now is a default case or a case where you specifically check if the user inputed C.
Example:
switch(DepositIndication) {
// All other cases ...
case 'c': {
// The user canceled the interaction
std::cout << "Interaction was canceled." << std::endl;
break;
}
// Default case to ensure that even,
// if the user hits any other key we still handle his interaction
default {
std::cout << "No fitting interactional behaviour found." << std::endl;
break;
}
}
If you want to ensure that the user can even input big lettered chars and the switch case will still work you can use std::tolower and cast it back to a char.
Make the User-Input lowercase:
// Make DepositIndication lowercase
DepositIndication = std::tolower(DepositIndication, std::locale());

Explain what this c++ bool line mean in this cpp book

playpen pp;
bool more(true);
do{
display_content();
int const choice(get_choice));
more = do_choice(pp, choice);
} while (more)
function code >>
bool do_choice(int choice){
bool more(true);
switch(choice){
case 0:
clear_playpen(???);
break;
case 1:
more = false;
break;
case 2:
change_plotmode(???);
break;
case 3:
plot_pixel(???);
break;
case 4:
change_scale(???);
break;
default:
throw problem("Not a valid option");
}
return more;
}
the do_choice function has a declaration bool do_choice(int choice);
with the last line in definition as return true to the bool type. Why will the author again in the cpp script above say more = do_choice(...) which I am understanding to mean true = true // what use is that? Sounds gibberish to me
You're confusing the assignment operator (=) with the comparison operator (==).
The call to do_choice updates more so the loop will stop eventually.

How to construct a class with variadic pointer functions as members?

I want to know whether the following is possible in C++. I need to construct a class that will store as a data member a std::map, with keys being of type std::string, and values being function pointers. The thing is that I want these function pointers to be variadic in the sense that they should point to functions accepting an arbitrary number of arguments, i.e. pointing to functions of the form
template<class... Args>
f(Args...);
The important bit is that I want to be able to have different arguments for the different function pointers in the map of a given instance of my class. For example, I might want to create an object of my class and have its map contain two pairs, one corresponding to a function having (double, int) as arguments, and another having (std::vector, int, int) as arguments. And I want to be able to make this general, in the sense that I want to be able to add new elements to the map, with possibly different argument lists (although I would only do this at compile-time, I still need to code the class without knowing about the types since I want to add the new elements from other files/clients).
What is the best way to implement this?
For all those saying you cant, you actually can, it's not pretty:
This is an example code from the output of the moc tool, that does exactly that: It stores an arbitrary amount of function / method pointers, with an arbitrary number of arguments.
Easiest Solution: Just use Qt's moc tool to generate that for you,
If you cannot or don't want to use Qt, you still can analize the code below on how they achieve it.
int AtCore::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 25)
qt_static_metacall(this, _c, _id, _a);
_id -= 25;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 25)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 25;
}
return _id;
}
void AtCore::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
AtCore *_t = static_cast<AtCore *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->printProgressChanged((*reinterpret_cast< const float(*)>(_a[1]))); break;
case 1: _t->receivedMessage((*reinterpret_cast< const QByteArray(*)>(_a[1]))); break;
case 2: _t->stateChanged((*reinterpret_cast< PrinterState(*)>(_a[1]))); break;
case 3: _t->print((*reinterpret_cast< const QString(*)>(_a[1]))); break;
case 4: _t->stop(); break;
case 5: _t->pause((*reinterpret_cast< const QString(*)>(_a[1]))); break;
case 6: _t->resume(); break;
case 7: _t->home((*reinterpret_cast< uchar(*)>(_a[1]))); break;
case 8: _t->home(); break;
case 9: _t->setExtruderTemp((*reinterpret_cast< uint(*)>(_a[1])),(*reinterpret_cast< uint(*)>(_a[2]))); break;
case 10: _t->setExtruderTemp((*reinterpret_cast< uint(*)>(_a[1]))); break;
case 11: _t->setExtruderTemp(); break;
case 12: _t->move((*reinterpret_cast< uchar(*)>(_a[1])),(*reinterpret_cast< uint(*)>(_a[2]))); break;
case 13: _t->setBedTemp((*reinterpret_cast< uint(*)>(_a[1]))); break;
case 14: _t->setBedTemp(); break;
case 15: _t->setFanSpeed((*reinterpret_cast< uint(*)>(_a[1])),(*reinterpret_cast< uint(*)>(_a[2]))); break;
case 16: _t->setFanSpeed((*reinterpret_cast< uint(*)>(_a[1]))); break;
case 17: _t->setFanSpeed(); break;
case 18: _t->setAbsolutePosition(); break;
case 19: _t->setRelativePosition(); break;
case 20: _t->setPrinterSpeed((*reinterpret_cast< uint(*)>(_a[1]))); break;
case 21: _t->setPrinterSpeed(); break;
case 22: _t->setFlowRate((*reinterpret_cast< uint(*)>(_a[1]))); break;
case 23: _t->setFlowRate(); break;
case 24: _t->close(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
void **func = reinterpret_cast<void **>(_a[1]);
{
typedef void (AtCore::*_t)(const float & );
if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&AtCore::printProgressChanged)) {
*result = 0;
return;
}
}
{
typedef void (AtCore::*_t)(const QByteArray & );
if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&AtCore::receivedMessage)) {
*result = 1;
return;
}
}
{
typedef void (AtCore::*_t)(PrinterState );
if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&AtCore::stateChanged)) {
*result = 2;
return;
}
}
}
}

Control may reach end of non-void function switch statement

I tried to do a simple calculator. Don't understand why i'm getting the warning that "Control may reach end of non-void function." for the f() function. Any suggestions?
Here is my code:
#include <iostream>
using namespace std;
int f(int a, int b, int i){
switch(i){
case 1: return a+b;
case 2: return a-b;
case 3: return a*b;
case 4: return a/b;
case 5: return a%b;
}
}
int main(){
char Continue='y';
int a,b,i;
cout<<"1.Add"<<endl<<"2.Subtract"<<endl<<"3.Multiply"<<endl<<"4.Divide"<<endl<<"5.modulus"<<endl;
do{
cout<<"Enter two numbers:"<<endl;
cin>>a;
cin>>b;
cout<<"Enter the number of what kind of caculation you want to do";
cin>>i;
cout<<f(a,b,i);
cout<<"Press y to continue/n";
cin>>Continue;
}while(Continue=='y');
}
Because if i is neither 1, 2, 3, 4, 5, then the execution passes over the entire switch statement completely, and there is no explicit return from a function that should return an int.
you need to add some type of default label into your switch statement, general syntax is as follows
switch(value)
{
case 0 :
//do something
break;
case 1:
break;
//// add any case as needed
default : // this would be the line you're missing
break;
}
non void means it doesn't return anything, it's the same thing as witting a function that returns a something, but instead you skip that part entirely
tldr you're esentially doing this
int non_void()
{
//do stuff but not return anything
}

I wanted to know how to properly use switch/case

I was just wondering if someone could just give me an example of how to use switch/case. I kinda get the just of it but am having trouble figuring out what and how i can use this. Thank you in advance.
There are couple of things to remember about switch case statements:
a) The condition should be integeral/enum/user defined type which supports conversion to int or enum
b) case lables are compile time constants
c) No two case label expressions can have the same value
d) $6.4.2/5- "When the switch statement is executed, its condition is evaluated and compared with each case constant. If one of the case constants is equal to the value of the condition, control is passed to the statement following the matched case label. If no case constant matches the condition, and if there is a default label,control passes to the statement labeled by the default label. If no case matches and if there is no default then none of the statements in the switch is executed."
e) $6.4.2/6- "case and default labels in themselves do not alter the flow of control, which continues unimpeded across such labels. To exit from a switch, see break"
enum direction {north, south, east, west};
char x;
class UD{
operator int(){return 0;}
};
direction f1(){
return north;
}
char f2(){
return 'A';
}
int main(){
direction d = f();
string country;
// switch condition of type enum
switch(d){
case north:
country = "P";
break;
case south:
country = "Q";
break;
case east:
country = "R";
break;
case west:
country = "S";
break;
default:
country = "";
break;
}
// switch condition of integral type
switch(c){
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
cout << "Vowel";
break;
default:
cout << "Not a Vowel";
break;
}
UD u;
// switch condition of user defined type (conversion to integral type)
switch(u){
case 0:
case 1:
cout << "Good";
break;
default:
cout << "Not so good";
break;
}
}
Here is a fairly typical use case. You have a list of values (the enum) and a switch which checks the input to determine which you are dealing with. This assumes of course that the action you will take depends on the underlying value of the enum.
enum ImageFormat
{
FormatRGB888,
FormatRGB8888,
FormatRGB101010,
FormatRGB161616,
FormatRGB16161616
};
void SomeFunc(ImageFormat format)
{
switch(format)
{
case FormatRGB888:
// do stuff
break;
case FormatRGB8888:
// do stuff
break;
case FormatRGB101010,
// do stuff
break;
case FormatRGB161616:
// do stuff
break;
case FormatRGB16161616:
// do stuff
break;
default:
// bad value for 'format'
}
}
Say you have an enum
enum expr_type {
EXPR_TYPE_ADD,
EXPR_TYPE_SUBTRACT,
EXPR_TYPE_GET_VALUE
};
We can do a switch on this:
enum expr_type t = /* get input somehow and find the type */;
switch(t) {
case EXPR_TYPE_ADD:
cout << "Operator Add";
/* fall through */
case EXPR_TYPE_SUBTRACT:
cout << "Operator (Add or Subtract)";
break;
case EXPR_TYPE_GET_VALUE;
cout << "Getting some value";
break;
}
You have to put in the break; so it doesn't fallthrough - Currently, EXPR_TYPE_ADD will exute all the code for EXPR_TYPE_SUBTRACT. Make sure to use break correctly!
Switch statements are a more efficient way of doing a lot of ifs and elses.
import java.util.Scanner;
class Date{
public static void main(String[] args) {
String dow;
String wowby;
String yowby;
Double n1,n2,res;
Scanner scan = new Scanner (System.in);
System.out.print("Enter Date (dd/mm/yy): ");
String date = scan.nextLine();
String dd = date.substring(0,2);
String mm = date.substring(3,5);
String yy = date.substring(6,8);
int d = Integer.valueOf(dd);
int m = Integer.valueOf(mm);
int y = Integer.valueOf(yy);
boolean valid = (d>=1) && (d<31)||(m>=1) && (m<12);//||((y>=00) && (y<99));
if(!valid)
System.out.print("Invalid date");
else {
switch (dd)
{
case "01":
System.out.print("First of ");
switch (mm) {
case "01":
System.out.print("January,2020");
break;
case "02":
System.out.print("February,2020");
break;
case "03":
System.out.print("March,2020");
break;
case "04":
System.out.print("April,2020");
break;
case "05":
System.out.print("May,2020");
break;
case "06":
System.out.print("June,2020");
break;
case "07":
System.out.print("July,2020");
break;
case "08":
System.out.print("August,2020");
break;
case "09":
System.out.print("September,2020");
break;
case "10":
System.out.print("October,2020");
break;
case "11":
System.out.print("November,2020");
break;
case "12":
System.out.print("December,2020");
break;
default:
System.out.print(" Invalid date ");
}
break;
case "02":
System.out.print("Second of ");
switch (mm)
{
case "01":
System.out.print("January,2020");
break;
case "02":
System.out.print("February,2020");
break;
case "03":
System.out.print("March,2020");
break;
case "04":
System.out.print("April,2020");
break;
case "05":
System.out.print("May,2020");
break;
case "06":
System.out.print("June,2020");
break;
case "07":
System.out.print("July,2020");
break;
case "08":
System.out.print("August,2020");
break;
case "09":
System.out.print("September,2020");
break;
case "10":
System.out.print("October,2020");
break;
case "11":
System.out.print("November,2020");
break;
case "12":
System.out.print("December,2020");
break;
default:
System.out.print(" Invalid month ");
}
break;
case "03":
System.out.print("Third of ");
switch (mm)
{
case "01":
System.out.print("January,2020");
break;
case "02":
System.out.print("February,2020");
break;
case "03":
System.out.print("March,2020");
break;
case "04":
System.out.print("April,2020");
break;
case "05":
System.out.print("May,2020");
break;
case "06":
System.out.print("June,2020");
break;
case "07":
System.out.print("July,2020");
break;
case "08":
System.out.print("August,2020");
break;
case "09":
System.out.print("September,2020");
break;
case "10":
System.out.print("October,2020");
break;
case "11":
System.out.print("November,2020");
break;
case "12":
System.out.print("December,2020");
break;
default:
System.out.print(" Invalid month ");
}
return;
}
}
}
}