How to make variables within a function accessible to the main function? - c++

I have some simple code below that I am having trouble getting to run correctly. Essentially, I have a custom function Create() that creates a variant (either Point, Line, Circle) depending on the users input. Then I call this function in the main function, and attempt to call on the variant that I created in Create(). This obviously doesnt work. How can this be fixed?
using boost::variant; //Using declaration for readability purposes
typedef variant<Point, Line, Circle> ShapeType; //typedef for ShapeType
ShapeType Create()
{
int shapenumber;
cout<<"Variant Shape Creator - enter '1' for Point, '2' for Line, or '3' for Circle: ";
cin>>shapenumber;
if (shapenumber == 1)
{
ShapeType mytype = Point();
return mytype;
}
else if (shapenumber == 2)
{
ShapeType mytype = Line();
return mytype;
}
else if (shapenumber == 3)
{
ShapeType mytype = Circle();
return mytype;
}
else
{
throw -1;
}
}
int main()
{
try
{
cout<<Create()<<endl;
Line lnA;
lnA = boost::get<Line>(mytype); //Error: identified 'mytype' is undefined
}
catch (int)
{
cout<<"Error! Does Not Compute!!!"<<endl;
}
catch (boost::bad_get& err)
{
cout<<"Error: "<<err.what()<<endl;
}
}

You need to store the return value:
ShapeType retShapeType = Create() ;
std::cout<<retShapeType<<std::endl;
....
lnA = boost::get<Line>( retShapeType );
You can not access values that are local to a scope(in this case if/else statements) outside of that scope. You can return values from functions which you are doing you just need to store that value to use it.

Related

How to transform a string in a function?

Indeed I have this code :
#include <iostream>
double a(){return 1.23;}
double b(){return 1.21;}
int main(){
std::string function0;
return EXIT_SUCCESS;
}
And what I want is this : if function0 = 'a' I would like to be able to transform the string function0 in the function a but I don't know how to do this. If function0 is equals to b I would like to call the function b.
Thank you for your help !
What you want to do is calling one of the functions depending on the value of the string variable. This is easily achievable.
An if else construct in the main():
if (function0 == "a") {
foo = a();
} else if (function0 == "b") {
foo = b();
}
Merge the function and modify the result, so it behaves differently depending on the input:
double newFunction (string input) {
double valueForA = 1.23;
double valueForB = 1.21;
if (input == "a") {
return valueForA;
} else if (input == "b") {
return valueForB;
} else {
//what if it's not "a" nor "b"?
return 0;
}
}
Usage:
double foo = newFunction(function0);
N.B:
Don't neglect the return values of your function, if the returned value is not important use void function.
Learn to use variables (instead of useless functions). You could have created 2 variables in the main, and that would be it.
Visit this link to get started with C++. Without good references, you'll hate learning it, and that would be sad, or would it?
Stop using the book/website you're currently using to learn programming. It's (probably) garbage.
function pointers may help.
double (*funcPtr)();
int main() {
if (function0 == "a")
funcPtr = &a;
else
funcPtr = &b;
(*funcPtr)(); //calling a() or b()
}

How to check if bool method returns value in an if statement C++

I'm having a go at creating classes and have created this method inside
Input.cpp:
bool Input::CheckKeyPress(char key)
{
SDL_Event ev;
while (SDL_PollEvent(&ev))
{
keyState = SDL_GetKeyboardState(NULL);
if (ev.type == SDL_KEYDOWN)
{
switch (key)
{
case 'w' :
if (keyState[SDL_SCANCODE_W])
{
return 1;
}
else
{
return 0;
}
case 'a' :
if (keyState[SDL_SCANCODE_A])
{
return 1;
}
else
{
return 0;
}
case 's' :
if (keyState[SDL_SCANCODE_S])
{
return 1;
}
else
{
return 0;
}
case 'd' :
if (keyState[SDL_SCANCODE_D])
{
return 1;
}
else
{
return 0;
}
}
}
}
}
I try to use it in an if-statement in my main class like so:
if (bool Input::CheckKeyPress(w))
{
//do stuff
}
However as expected I get an error saying: "A function type is not allowed here" So what do I do?
Just write:
if (CheckKeyPress(w))
{
//do stuff
}
You have already told the compiler that the CheckKeyPress() method returns a bool. Here, you are just calling the function, so you don't need to mention the return type again. When the control will call the function CheckKeyPress(), it will return a bool value that would be checked for its truth within the if statement.
Note: There are two possibilities:
Instance is a different class:
If Instance is altogether a different class and CheckKeyPress() is
one of the methods that it contains, then you first need to create an object of the Instance class like below:
Instance it = new Instance(); //or just Instance it;
and then access the function via:
it.CheckKeyPress();
If the method is static:
In this case you need to call the method as:
Input::CheckKeyPress(w)
without just the return type (bool).
Hope this is helpful. Thank you for your inputs, #user4581301.

Getting a strange int value

When I cout my lettercase variable to the console, I get -858993460. Everything else seems to be working okay. What am I missing here?
So here's a sample of my code:
Here's main:
int main()
{
int lettercase = 0;
Switch switcher(lettercase);
lettercase = switcher.getLettercase();
cout << "Lettercase: " << lettercase << endl;
return 0;
}
I also have a separate class called Switch.
Here's a sample of its header file:
class Switch {
public:
// DEFAULT CONSTRUCTOR
Switch();
// OVERLOAD CONSTRUCTOR
Switch(int);
// DESTRUCTOR
~Switch();
// Lettercase accessor
int getLettercase();
private:
int lettercase;
};
And here's a sample of my definition:
// DEFAULT
Switch::Switch() {
int lettercase = 0;
}
// OVERLOAD
Switch::Switch(int lettercase) {
// CHANGE LETTER CASE
if (lettercase == 1) {
lettercase = 0;
} else {
lettercase = 1;
}
}
// DESTRUCTOR
Switch::~Switch() {
}
// ACCESSOR
int Switch::getLettercase() {
return lettercase;
}
// OVERLOAD
Switch::Switch(int lettercase) {
// CHANGE LETTER CASE
if (lettercase == 1) {
lettercase = 0;
} else {
lettercase = 1;
}
}
You have scope issues here. You're trying to change the class variable lettercase, but because the argument for the constructor is also called lettercase, you have to use this->lettercase if you want to access the class variable. I suggest changing the name of your parameter here.
Something like this:
// OVERLOAD
Switch::Switch(int initCase) {
// CHANGE LETTER CASE
if (initCase == 1) {
lettercase = 0;
} else {
lettercase = 1;
}
}
The reason you were getting that odd int is because your scope issues prevented you from ever initializing the class variable lettercase, but your getter was still accessing this variable and returning the uninitialized value.
EDIT: Your default constructor also has a problem, here:
Switch::Switch() {
int lettercase = 0;
}
This isn't doing what you think it's doing (or what you want it to do). Rather than initializing the class variable, lettercase, this is creating a new variable, lettercase, (scope) and initializes it to 0. Instead, your default constructor should look like this:
Switch::Switch() {
lettercase = 0;
}

C++ Dynamically Define Function

I am on visual c++ working on a console calculator, I am creating a way to let the user define a custom linear function. Here is where I am stumped: Once I get the users desired name of the function, the slope, and the y-intercept, I need to use that data to create a callable function that I can pass to muParser.
In muParser, you define custom functions like this:
double func(double x)
{
return 5*x + 7; // return m*x + b;
}
MyParser.DefineFun("f", func);
MyParser.SetExpr("f(9.5) - pi");
double dResult = MyParser.Eval();
How could I dynamically create a function like this based on the users input for the values 'm' and 'b' and pass that to the 'DefineFun()' method?
This is what I have so far:
void cb_SetFunc(void)
{
string FuncName, sM, sB;
double dM, dB;
bool GettingName = true;
bool GettingM = true;
bool GettingB = true;
regex NumPattern("[+-]?(?:0|[1-9]\\d*)(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?");
EchoLn(">>> First, enter the functions name. (Enter 'cancel' to abort)");
EchoLn(">>> Only letters, numbers, and underscores can be used.");
try
{
do // Get the function name
{
Echo(">>> Enter name: ");
FuncName = GetLn();
if (UserCanceled(FuncName)) return;
if (!ValidVarName(FuncName))
{
EchoLn(">>> Please only use letters, numbers, and underscores.");
continue;
}
GettingName = false;
} while (GettingName);
do // Get the function slope
{
Echo(">>> Enter slope (m): ");
sM = GetLn();
if (UserCanceled(sM)) return;
if (!regex_match(sM, NumPattern))
{
EchoLn(">>> Please enter any constant number.");
continue;
}
dM = atof(sM.c_str());
GettingM = false;
} while (GettingM);
do // Get the function y-intercept
{
Echo(">>> Enter y-intercept (b): ");
sB = GetLn();
if (UserCanceled(sB)) return;
if (!regex_match(sB, NumPattern))
{
EchoLn(">>> Please enter any constant number.");
continue;
}
dB = atof(sB.c_str());
GettingB = false;
} while (GettingB);
// ------------
// TODO: Create function from dM (slope) and
// dB (y-intercept) and pass to 'DefineFun()'
// ------------
}
catch (...)
{
ErrMsg("An unexpected error occured while trying to set the function.");
}
}
I was thinking that there isn't a way to define an individual method for each user-defined-function. Would I need to make a vector<pair<double, double>> FuncArgs; to keep track of the appropriate slopes and y-intercepts then call them dynamically from the function? How would I specify which pair to use when I pass it to DefineFun(FuncStrName, FuncMethod)?
What you need (in addition to a script language interpreter) is called a "trampoline". There is no standard solution to create those, in particular since it involves creating code at runtime.
Of course, if you accept a fixed number of trampolines, you can create them at compile time. And if they're all linear, this might be even easier:
const int N = 20; // Arbitrary
int m[N] = { 0 };
int b[N] = { 0 };
template<int I> double f(double x) { return m[I] * x + b; }
This defines a set of 20 functions f<0>...f<19> which use m[0]...m[19] respectively.
Edit:
// Helper class template to instantiate all trampoline functions.
double (*fptr_array[N])(double) = { 0 };
template<int I> struct init_fptr<int I> {
static const double (*fptr)(double) = fptr_array[I] = &f<I>;
typedef init_fptr<I-1> recurse;
};
template<> struct init_fptr<-1> { };
I would keep it simple:
#include <functional>
std::function<double(double)> f; // this is your dynamic function
int slope, yintercept; // populate from user input
f = [=](double x) -> double { return slope * x + yintercept; };
Now you can pass the object f to your parser, which can then call f(x) at its own leisure. The function object packages the captured values of slope and yintercept.
GiNaC is C++ lib which can parse and evaluate math expressions.
Generating a fixed array of functions bindable to boost function.
Someone else already said about a similar method, but since I'd taken the time to write the code, here it is anyway.
#include <boost/function.hpp>
enum {
MAX_FUNC_SLOTS = 255
};
struct FuncSlot
{
double (*f_)(double);
boost::function<double(double)> closure_;
};
FuncSlot s_func_slots_[MAX_FUNC_SLOTS];
template <int Slot>
struct FuncSlotFunc
{
static void init() {
FuncSlotFunc<Slot-1>::init();
s_func_slots_[Slot - 1].f_ = &FuncSlotFunc<Slot>::call;
}
static double call(double v) {
return s_func_slots_[Slot - 1].closure_(v);
}
};
template <> struct FuncSlotFunc<0> {
static void init() {}
};
struct LinearTransform
{
double m_;
double c_;
LinearTransform(double m, double c)
: m_(m)
, c_(c)
{}
double operator()(double v) const {
return (v * m_) + c_;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
FuncSlotFunc<MAX_FUNC_SLOTS>::init();
s_func_slots_[0].closure_ = LinearTransform(1, 0);
s_func_slots_[1].closure_ = LinearTransform(5, 1);
std::cout << s_func_slots_[0].f_(1.0) << std::endl; // should print 1
std::cout << s_func_slots_[1].f_(1.0) << std::endl; // should print 6
system("pause");
return 0;
}
So, you can get the function pointer with: s_func_slots_[xxx].f_
And set your action with s_func_slots_[xxx].closure_
Try to embed to your application some script language. Years ago I was using Tcl for similar purpose - but I do not know what is the current time best choice.
Either you can start from Tcl or search yourself for something better:
See: Adding Tcl/Tk to a C application

How to implement final conditions properly?

This is what I'm trying to do (this is a simplification of a real project):
int param;
int result;
void isolated(int p) {
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
} catch (...) {
throw "problems..";
}
}
I can't change the way process() works, since this function is not created in the project and is a third-party function. It works with global variables param and result and we can't change this.
The problem appears when isolated() is called back from process() with another parameter. I want to catch this situation, but don't know how to do it, since finally is absent in C++. I feel that I should use RAII technique, but can't figure out how to do it in this case properly.
This is how I can make it with code duplication:
int param;
int result;
void isolated(int p) {
static bool running;
if (running) {
throw "you can't call isolated() from itself!";
}
running = true;
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
running = false;
} catch (...) {
running = false; // duplication!
throw "problems..";
}
}
"finally" like situations are handled in C++ using guard objects, that do their finally thing in the destructor. This is IMHO much more powerful approach, because you have to analyze the situation to finalize in order to create a reuseable object. In this case, we need to make process rentrant, because parameters and returns are passed in globals. The solution is to save their values on entry and restore them on exit:
template<class T>
class restorer
{
T &var; // this is the variable we want to save/restore
T old_value; // the old value
restorer(const restorer&);
void operator=(const restorer&);
public:
restorer(T &v) : var(v), old_value(v) {}
~restorer() { var=old_value; }
};
int param;
int result;
int isolated(int p) {
restorer<int> rest_param(param);
restorer<int> rest_result(result);
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
return result;
} catch (...) {
return 0;
}
}
Maybe I didn't get it right, but why don't you use a flag? You want to know when the isolated() is called from the process(), right?
int isolated(int p) {
static int execDeep = 0;
execDeep++;
// your code here
execDeep--;
}
Now you can check 'execDeep' value, > 1 means it is called from the process() while still being executed.
I still don't quite sure how finally is related here, but you could try Boost.ScopeExit if you want to avoid creating a scope guard structure yourself.
Example:
#include <boost/scope_exit.hpp>
#include <cstdio>
int isolated(int p) {
static bool running = false;
if (running) {
printf("Throwing %d\n", p);
throw p;
}
printf("Starting %d\n", p);
running = true;
BOOST_SCOPE_EXIT( (p)(&running) ) { // <--
printf("Stopping %d\n", p); // <--
running = false; // <--
} BOOST_SCOPE_EXIT_END // <--
// ...
if (p)
isolated(p*10);
// ...
printf("Returing %d\n", p);
return 4;
}
int main() {
printf(">> first\n");
isolated(0);
printf(">> second\n");
try {
isolated(1);
printf(">> third (should not be printed.)\n");
} catch(int p) {
printf("Caught %d\n", p);
}
isolated(0);
printf(">> fourth\n");
return 0;
}
Result:
>> first
Starting 0
Returing 0
Stopping 0
>> second
Starting 1
Throwing 10
Stopping 1
Caught 10
Starting 0
Returing 0
Stopping 0
>> fourth
Could this work?
int save = -10000000000;
int param;
int result;
int isolated(int p) {
if (save != -10000000000)
{
// run the other condition
}
else
{
save = p;
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
return result;
} catch (...) {
return 0;
}
}
}
If I understand correctly, you want to automatically set the running flag to false at the end of function. If that is the requirement then you can use the ScopeGuard approarch mentioned in the link.