std::stol corrupts stack on failure - c++

class.h
// class.h
#pragma once
#include <string>
#include <iostream>
class TV {
public:
TV() {}
TV(std::string, std::string, std::string, std::string, std::string);
private:
int member;
};
main.cpp:
//main.cpp
#include "class.h"
TV::TV(std::string a, std::string b, std::string c, std::string d, std::string e) {
try {
member = std::stol(a);
if (member <= 0)
throw;
}
catch (...) {
std::cout << "Invalid argument" << std::endl;
}
}
int main(int argc, char *argv[]) {
new TV("TEST","NAME","0.1","0.1","0.1");
};
So it turns out that if I provided std::stol with an invalid_argument, then in gdb all other arguments passed to the function would appear corrupted.
Can anyone explain why this happens?

Related

how transfer function from template class

#include <iostream>
#include <windows.h>
#include <string.h>
#include <functional>
#include <stdint.h>
#include <stdio.h>
using namespace std;
template <typename T>
class someclass {
public:
T value;
int sum(int vl1, int vl2) { return vl1 + vl2; };
};
template <typename T>
class someclass2 {
public:
T value;
void print(const std::function<int(int, int)>& func) {
cout << func(3, 4) << '\n';
};
};
int main(int argc, const char **argv)
{
someclass<int> obj1;
someclass2<int> obj2;
obj2.print(obj1.sum);
}
Compiler show error on last line : error C3867: 'someclass::sum': non-standard syntax; use '&' to create a pointer to member
Note that
int sum(int vl1, int vl2) { return vl1 + vl2; };
doesn't use its owner class' member in any way, it safely can be declared static, in that case this code would work.
The problem with this code is that a member function got a different type from standalone function. It's a member of class someclass, so its type is int (someclass::*)(int, int) and to call it you need an instance of that class.
The literal solution in general case is to hide pass of this inside the functor created by lambda expression:
obj2.print( [&](int a, int b)-> int { return obj1.sum(a,b); } );
You can use std::bind to do that
int main(int argc, const char **argv)
{
someclass<int> obj1;
someclass2<int> obj2;
using namespace std::placeholders;
obj2.print(std::bind(&someclass<int>::sum, &obj1, _1, _2));
}

C++ std::vector assign methods

has anyone an idea how I can realize this with working code?
My wish is to fill a vector with executable methods of a class...
#include <iostream>
#include <vector>
#include <any>
class foo {
public:
void boo() {
std::cout << "WM 2018" << std::endl;
}
};
int main(int argc, char const *argv[])
{
std::vector<std::any> vec;
vec.push_back( (new foo)->boo() );
vec[0]();
return 0;
}
It seems you want std::vector<std::function<void()>>:
std::vector<std::function<void()>> vec{[](){ foo{}.boo();}};
Demo

object as key to map becomes const in cpp

can someone please explain why the following code compilation fails with message "passing ‘const apple’ as ‘this’ argument of ‘int apple::foo()’ discards qualifiers", and how to resolve it.
#include <cstdlib>
#include <iostream>
#include <string>
#include <map>
using namespace std;
/*
*
*/
class apple{
private:
int a,b,c,d;
public:
int foo(){
return a+b+c+d;
}
};
class ball{
private:
map<apple,string> mp;
public:
void foo2(){
for(map<apple,string>::iterator it = mp.begin();it!=mp.end();++it){
cout<<it->first.foo()<<endl;
}
}
}
int main(int argc, char** argv) {
return 0;
}
Works for me: (added const at the end of foo() and ; on end of ball class). Class apple is a Key in std::map which is declared as const: typedef pair value_type; so accessing key should be also declared as const.
#include <map>
#include <iostream>
using namespace std;
class apple{
private:
int a,b,c,d;
public:
int foo() const {
return a+b+c+d;
}
};
class ball{
private:
map<apple,string> mp;
public:
void foo2(){
for(map<apple,string>::iterator it = mp.begin();it!=mp.end();++it){
cout<<it->first.foo()<<endl;
}
}
};
int main(int argc, char** argv) {
return 0;
}

using boost::function with instance methods

I am trying to use boost::function with instance methods using the following example
class someclass
{
public:
int DoIt(float f, std::string s1)
{
return 0;
}
int test(boost::function<int(float, std::string)> funct)
{
//Funct should be pointing to DoIt method here
funct(12,"SomeStringToPass");
}
void caller()
{
test(DoIt); //Error : 'someclass::DoIt': function call missing argument list; use '&someclass::DoIt' to create a pointer to member
}
};
Any suggestion on how I could resolve this issue ?
You should use boost::bind:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
using namespace std;
class someclass
{
public:
int DoIt(float f, std::string s1)
{
return 0;
}
int test(boost::function<int(float, std::string)> funct)
{
return funct(5.0, "hello");
}
void caller()
{
cout << test(boost::bind(&someclass::DoIt, this, _1, _2)) << endl;
}
};
int main() {
someclass s;
s.caller();
}

Passing string as reference to function pointer c++

Below is my code
#include "stdafx.h"
#include <string.h>
#include <iostream.h>
using namespace std;
class ToDoCommands
{
public:
void getCommand(string);
};
void ToDoCommands::getCommand(string command)
{
cout<<command; //here i get ping
void (*CommandToCall)(void);
CommandToCall = command; // error here i want something like
// CommandToCall = ping
CommandToCall();
}
void ping(void)
{
cout<<"ping command executed";
}
int main()
{
ToDoCommands obj;
obj.getCommand("ping");
}
The function pointer should refer to function ping dynamically. A string same as function name is passed to getCommand function in main.
C++ just doesn't work that way. If you really need something like that, you'll have to make a table of functions that are indexed by name:
#include <assert.h>
#include <iostream>
#include <map>
#include <string>
using std::cout;
using std::string;
using std::map;
void ping(void)
{
cout << "ping command executed\n";
}
class ToDoCommands
{
public:
typedef void (*FunctionPtr)();
typedef string Name;
void registerFunction(Name name,FunctionPtr);
void callFunction(Name);
private:
map<Name,FunctionPtr> func_map;
};
void ToDoCommands::registerFunction(Name name,FunctionPtr func_ptr)
{
func_map[name] = func_ptr;
}
void ToDoCommands::callFunction(Name name)
{
assert(func_map.find(name)!=func_map.end());
func_map[name]();
}
int main(int argc,char **argv)
{
ToDoCommands to_do_commands;
to_do_commands.registerFunction("ping",ping);
to_do_commands.callFunction("ping");
return 0;
}
void ping(void)
{
// LL DD…DD XX
cout<<"ping command executed"<<endl;
}
class ToDoCommands
{
public:
void getCommand( void (*CommandToCall)(void)); //getCommand(ping)
};
void ToDoCommands::getCommand( void (*CommandToCall)(void) )
{
void (*CommandToCall1)(void);
CommandToCall1 = CommandToCall;
CommandToCall1();
}
int main()
{
ToDoCommands obj;
obj.getCommand( ping );
return 0;
}
i tried this and its working :)