I wonder if there is a simple way to call a function from a string. I know a simple way, using 'if' and 'else'.
int function_1(int i, int j) {
return i*j;
}
int function_2(int i, int j) {
return i/j;
}
...
...
...
int function_N(int i, int j) {
return i+j;
}
int main(int argc, char* argv[]) {
int i = 4, j = 2;
string function = "function_2";
cout << callFunction(i, j, function) << endl;
return 0;
}
This is the basic approach
int callFunction(int i, int j, string function) {
if(function == "function_1") {
return function_1(i, j);
} else if(function == "function_2") {
return function_2(i, j);
} else if(...) {
} ...
...
...
...
return function_1(i, j);
}
Is there something simpler?
/* New Approach */
int callFunction(int i, int j, string function) {
/* I need something simple */
return function(i, j);
}
What you have described is called reflection and C++ doesn't support it. However you might come with some work-around, for example in this very concrete case you might use an std::map that would map names of functions (std::string objects) to function pointers, which in case of functions with the very same prototype could be easier than it might seem:
#include <iostream>
#include <map>
int add(int i, int j) { return i+j; }
int sub(int i, int j) { return i-j; }
typedef int (*FnPtr)(int, int);
int main() {
// initialization:
std::map<std::string, FnPtr> myMap;
myMap["add"] = add;
myMap["sub"] = sub;
// usage:
std::string s("add");
int res = myMap[s](2,3);
std::cout << res;
}
Note that myMap[s](2,3) retrieves the function pointer mapped to string s and invokes this function, passing 2 and 3 to it, making the output of this example to be 5
Using a map of standard string to standard functions.
#include <functional>
#include <map>
#include <string>
#include <iostream>
int add(int x, int y) {return x+y;}
int sub(int x, int y) {return x-y;}
int main()
{
std::map<std::string, std::function<int(int,int)>> funcMap =
{{ "add", add},
{ "sub", sub}
};
std::cout << funcMap["add"](2,3) << "\n";
std::cout << funcMap["sub"](5,2) << "\n";
}
Even better with Lambda:
#include <functional>
#include <map>
#include <string>
#include <iostream>
int main()
{
std::map<std::string, std::function<int(int,int)>> funcMap =
{{ "add", [](int x, int y){return x+y;}},
{ "sub", [](int x, int y){return x-y;}}
};
std::cout << funcMap["add"](2,3) << "\n";
std::cout << funcMap["sub"](5,2) << "\n";
}
You can also put your functions into a shared library. You will load such library dynamically with dlopen() and then just make the calls to the functions with a std::string. Here an example:
hello.cpp
#include <iostream>
extern "C" void hello() {
std::cout << "hello" << '\n';
}
main.cpp
#include <iostream>
#include <dlfcn.h>
int main() {
using std::cout;
using std::cerr;
cout << "C++ dlopen demo\n\n";
// open the library
cout << "Opening hello.so...\n";
void* handle = dlopen("./hello.so", RTLD_LAZY);
if (!handle) {
cerr << "Cannot open library: " << dlerror() << '\n';
return 1;
}
// load the symbol
cout << "Loading symbol hello...\n";
typedef void (*hello_t)();
// reset errors
dlerror();
std::string yourfunc("hello"); // Here is your function
hello_t hello = (hello_t) dlsym(handle, yourfunc.c_str());
const char *dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol 'hello': " << dlsym_error <<
'\n';
dlclose(handle);
return 1;
}
// use it to do the calculation
cout << "Calling hello...\n";
hello();
// close the library
cout << "Closing library...\n";
dlclose(handle);
}
compilation:
g++ -fPIC -shared hello.cpp -o hello.so
and:
g++ main.cpp -o main -ldl
run:
C++ dlopen demo
Opening hello.so...
Loading symbol hello...
Calling hello...
hello
Closing library...
The example was stolen from here. There you can find more detailed explanation on dlopen() and c++
There is another possibility which hasn't been mentioned yet, which is true reflection.
An option for this is accessing functions exported from an executable or a shared library using operating system functions for resolving names to addresses. This has interesting uses like loading two 'contestant' dlls into an 'umpire' program, so that people can slug it out by having their actual codes fight each other (playing Reversi or Quake, whatever).
Another option is accessing the debug information created by the compiler. Under Windows this can be surprisingly easy for compilers that are compatible, since all the work can be off-loaded to system dlls or free dlls downloadable from Microsoft. Part of the functionality is already contained in the Windows API.
However, that falls more into the category of Systems Programming - regardless of language - and thus it pertains to C++ only insofar as it is the Systems Programming language par excellence.
Related
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
I'm trying to implement an output filter for logging and have modified some example code with unexpected results. The code is
#include <ctype.h> // toupper
#include <boost/iostreams/categories.hpp> // output_filter_tag
#include <boost/iostreams/operations.hpp> // put
#include <boost/iostreams/filtering_stream.hpp>
// cobbled from http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/concepts/output_filter.html#examples
//
// g++ [-DTEST] -o t-pri t-pri.cpp
using namespace std;
namespace io = boost::iostreams;
int pri=4;
struct toupper_output_filter {
typedef char char_type;
typedef io::output_filter_tag category;
template<typename Sink>
bool put(Sink& snk, char c)
{
if(pri<3)
return io::put(snk, /* toupper((unsigned char) c)*/ c);
else
return 0;
}
};
int main(int argc, char**argv)
{
boost::iostreams::filtering_ostream out;
out.push(toupper_output_filter());
cout << "pri: " << pri << endl;
out.push(cout);
out << "test-1" << endl;
#ifdef TEST
pri=2;
out << "test-2" << endl;
#endif
return 0;
}
The unexpected behavior is encountered when the TEST macro is defined:
hbarta#itws007:~/Documents/C++/t-pri$ g++ -o t-pri t-pri.cpp
hbarta#itws007:~/Documents/C++/t-pri$ ./t-pri
pri: 4
hbarta#itws007:~/Documents/C++/t-pri$ g++ -DTEST -o t-pri t-pri.cpp
hbarta#itws007:~/Documents/C++/t-pri$ ./t-pri
pri: 4
test-1
test-2
hbarta#itws007:~/Documents/C++/t-pri$
It seems as if the expression 'if(pri<3)' is evaluated once when the structure member function is first being called. I expect it to be evaluated every time something is streamed to 'out.'
As an aside, I'm working toward something that logs to the console (or perhaps a file) and has the capability to filter based on bitmap. IOW, a mask would be defined and bits set in it to enable specific output statements to actually write something. Code could look like (where mask is anded with enable)
<sometype> mask(0x0101);
out << enable(0x0010) << "log message" << endl; // not output
out << enable(0x0100) << "another log message" << endl; // is output
This seems like a common sort of thing that a developer might want to do but I am unable to find an example to copy. I'm working toward a solution and ran into this.
Thanks!
Edit: Trying to add to the solution per Nikita's suggestion by adding the setPri class to use as an iomanip with an argument. Still not working as expected All output is cached until the program exits and then the last setPri() insertion takes effect. Is that how Boost iostreams should work?
#include <boost/iostreams/categories.hpp> // output_filter_tag
#include <boost/iostreams/operations.hpp> // put
#include <boost/iostreams/filtering_stream.hpp>
using namespace std;
namespace io = boost::iostreams;
// cobbled from http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/concepts/output_filter.html#examples
//
// g++ -o to_upper to_upper.cpp
//
// Adding an iomanip with argument as in
// http://stackoverflow.com/questions/20792101/how-to-store-formatting-settings-with-an-iostream
// don't really want file scope variables...
static int pri=0; // value for a message
static int mask=1; // mask for enabled output (if pri&mask => output)
static int priIDX() { // find index for storing priority choice
static int rc = ios_base::xalloc();
return rc;
}
class setPri // Store priority in stream (but how to retrieve when needed?)
{
size_t _n;
public:
explicit setPri(size_t n): _n(n) {}
size_t getn() const {return _n;}
friend ostream& operator<<(ostream& os, const setPri& obj)
{
size_t n = obj.getn();
pri = n;
os << "setPri(" << n << ")"; // indicate update
return os;
}
};
struct toupper_output_filter {
typedef char char_type;
typedef io::output_filter_tag category;
template<typename Sink>
bool put(Sink& snk, char c)
{
if(pri & mask) // Should this char be sent to output?
return io::put(snk, c);
else
return 0;
}
};
int main(int argc, char**argv)
{
boost::iostreams::filtering_ostream out;
out.push(toupper_output_filter());
out.push(cout);
out << setPri(1) << " test-1" << endl;
out << setPri(2) << " test-2" << endl;
out << setPri(3) << " test-3" << endl;
return 0;
}
result is
setPri(1) test-1
setPri(2) test-2
setPri(3) test-3
The problem here is that toupper_output_filter applied to the output sequence after the pri variable changed to 2.
Statement out << "test-1" << endl; doesn't filter the sequence, it puts symbols into the buffer for the further procession. After that pri=2; and more symbols goes to the buffer at out << "test-2" << endl;. Before leaving the scope out filters it's buffer and outputs final symbols sequence. At this point pri is 2 and all the lines printed.
To fix the issue you could remove global state:
struct toupper_output_filter {
typedef char char_type;
typedef io::output_filter_tag category;
int pri;
toupper_output_filter (int logLevel)
{
pri = logLevel;
}
template<typename Sink>
bool put(Sink& snk, char c)
{
if(pri<3)
return io::put(snk, /* toupper((unsigned char) c)*/ c);
else
return 0;
}
};
And use it:
int main(int argc, char**argv)
{
boost::iostreams::filtering_ostream out;
int pri = 4;
out.push(toupper_output_filter(pri));
cout << "pri: " << pri << endl;
out.push(cout);
out << "test-1" << endl;
out.pop();
out.pop();
#ifdef TEST
pri=2;
out.push(toupper_output_filter(pri));
out.push(cout);
out << "test-2" << endl;
#endif
return 0;
}
Update:
The main idea of setPri class is to remove the static state and to manipulate priority with operator<<.
Draft for the solution:
static int mask=1; // mask for enabled output (if pri&mask => output)
struct toupper_output_filter {
typedef char char_type;
struct category : boost::iostreams::output_filter_tag {};
int pri;
toupper_output_filter(int n)
{
pri = n;
}
template<typename Sink>
bool put(Sink& snk, char c)
{
if(pri & mask) // Should this char be sent to output?
return io::put(snk, c);
else
return 0;
}
};
class setPri // Store priority in stream (but how to retrieve when needed?)
{
size_t _n;
public:
explicit setPri(size_t n): _n(n) {}
size_t getn() const {return _n;}
friend boost::iostreams::filtering_ostream& operator<<(boost::iostreams::filtering_ostream& out, const setPri& obj)
{
if (!out.empty())
{
out.pop();
out.pop();
}
out.push(toupper_output_filter(obj.getn()));
out.push(cout);
return out;
}
};
int main(int argc, char**argv)
{
boost::iostreams::filtering_ostream out;
out << setPri(1) << " test-1" << endl;
out << setPri(2) << " test-2" << endl;
out << setPri(3) << " test-3" << endl;
return 0;
}
Output is:
test-1
test-3
This post treats the same error, but the poster isn't have trouble with a void function.
This post concerns the "void" type of function, but the poster is advised to change the function type to "string", which does not help my case.
My code executes fine, except for a literal "0" at the end of the output. When I change the function type to "void", I am met with the above error.
I have been through the tutorial on this numerous times, and have searched thoroughly, yet have been unable to resolve this issue.
//my code
#include <iostream>
using namespace std;
int intervalcountdown (int a, int b) {
for(a; a>0; a = a - b) {
cout << a;
if(a<=b) {
break;
}
cout << ",";
}
cout << ".";
return 0;
}
int main () {
cout << intervalcountdown(20,3);
return 0;
}
Just don't print what you don't want.
#include <iostream>
using namespace std;
void intervalcountdown (int a, int b) { // change return type to void
for(; a>0; a = a - b) { // meaningless a is removed
cout << a;
if(a<=b) {
break;
}
cout << ",";
}
cout << ".";
// remove the return statement because the return type is now void
}
int main () {
intervalcountdown(20,3); // remove extra printing
return 0;
}
Why does this work:
#include "iostream"
class Something {
private:
static int s_nIDGenerator;
int m_nID;
friend int main();
public:
Something() { m_nID = s_nIDGenerator++; }
int GetID() const { return m_nID; }
};
int Something::s_nIDGenerator;
int main() {
Something::s_nIDGenerator = 1;
Something cFirst;
Something cSecond;
Something cThird;
using namespace std;
cout << cFirst.GetID() << endl;
cout << cSecond.GetID() << endl;
cout << cThird.GetID() << endl;
return 0;
}
it prints:
1
2
3
And this fail:
#include "iostream"
namespace test {
class Something {
private:
static int s_nIDGenerator;
int m_nID;
friend int main();
public:
Something() { m_nID = s_nIDGenerator++; }
int GetID() const { return m_nID; }
};
};
int test::Something::s_nIDGenerator;
int main() {
using namespace test;
Something::s_nIDGenerator = 1;
// or test::Something::s_nIDGenerator = 1; same effect if not using using.
Something cFirst;
Something cSecond;
Something cThird;
using namespace std;
cout << cFirst.GetID() << endl;
cout << cSecond.GetID() << endl;
cout << cThird.GetID() << endl;
return 0;
}
With the compiler error message of:
**** Internal Builder is used for build ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o src\tuttest1.o ..\src\tuttest1.cpp
..\src\tuttest1.cpp: In function 'int main()':
..\src\tuttest1.cpp:23:5: error: 'int test::Something::s_nIDGenerator' is private
..\src\tuttest1.cpp:27:13: error: within this context
Build error occurred, build is stopped
Time consumed: 161 ms.
How do I get the 2nd example to work using the namespace test?
How/Why is the namespace declaration around the object preventing the static member form being accessible?
Per my comment to #zmo, here is what I got to work based on his clue:
(comment doesn't have the space or formatting for this, and I had to edit because I couldn't set this an answer.... (what ever it takes.)
#include "iostream"
namespace test {
class Something {
private:
static int s_nIDGenerator;
int m_nID;
friend void load(int);
public:
Something() { m_nID = s_nIDGenerator++; }
int GetID() const { return m_nID; }
};
int Something::s_nIDGenerator;
void load (int value) {
Something::s_nIDGenerator = value;
}
};
int main() {
using namespace test;
load (1);
Something cFirst;
Something cSecond;
Something cThird;
using namespace std;
cout << cFirst.GetID() << endl;
cout << cSecond.GetID() << endl;
cout << cThird.GetID() << endl;
return 0;
}
I am still a little loose as to the "what's up with static members being in a class and a namespace not working?" What's up with this? Why didn't test::Something::s_nIDGenerator work? (still a part of my original question.) So, we are half-answered, so far.
I want to know why this didn't work so I don't walk into this rake again.
Probably because your friend int main() declaration is declaring that the namespace also has a free main() function, while the real main() function is not in the namespace.
To fix it? First declare int main(); before (and outside) namespace test, then friend int ::main() to indicate it's in the global namespace.
For more details, see this question.
well, though I will never recommand you to do like you did in your question, here is how to make your code work "as is" :
#include <iostream>
int main(); // declare main beforehands so it can be seen by Something
namespace test {
class Something {
private:
static int s_nIDGenerator;
int m_nID;
friend int ::main(); // take the main from global namespace
public:
Something() { m_nID = s_nIDGenerator++; }
int GetID() const { return m_nID; }
};
};
int test::Something::s_nIDGenerator;
int main() {
using namespace test;
Something::s_nIDGenerator = 1; // tada that works
Something cFirst;
Something cSecond;
Something cThird;
using namespace std;
cout << cFirst.GetID() << endl;
cout << cSecond.GetID() << endl;
cout << cThird.GetID() << endl;
return 0;
}
but here is a wrong use case of a friend function. The solution that seemed to work for you that I suggested (use a function inside your class Something) is far better for readability and understandability.
int main()
{
int i;
pthread_t t;
}
Can t not see i? t is created inside main, right? That means it must be using the same shared memory main() is using? How do I make it see i without making i a global variable?
pthreads aren't special. For instance, the following code has the same "problem":
void foo()
{
i = 5;
}
int main()
{
int i;
foo();
}
Surely foo is called by main, so they're even on the same thread. Yet foo doesn't see the int in main. The solution is simple: if foo needs an int, main should pass that:
void foo(int& i)
{
i = 5;
}
int main()
{
int i;
foo(i);
}
With threads, the situation is the same: pass what you need to share.
What? t is a thread, it doesn't really "see" anything. Strictly, it's a variable that represents a thread -- you haven't actually created a thread -- but assuming you do create one, it runs in the same process as main(), so it shares memory space in that sense, but it doesn't share the scope of main. The functions which run in that thread can see whatever variables are in scope for those functions.
You could pass a pointer to i as the user data pointer to pthread_create. Or if you need to access more than just i, you could pass a pointer to some structure which contains (among other things) a pointer to i, and so on.
Example code:
#include <pthread.h>
#include <iostream>
#include <cstring>
void *thread_entry_point(void *data) {
int *idata = static_cast<int*>(data);
std::cout << "thread: i = " << *idata << "\n";
*idata = 23;
return const_cast<char*>("might as well return something");
}
int main() {
int i = 12;
pthread_t thr;
int err = pthread_create(&thr, 0, thread_entry_point, &i);
if (err == 0) {
void *result;
pthread_join(thr, &result);
std::cout << "main: result = " << static_cast<const char*>(result) << "\n";
std::cout << "main: i = " << i << "\n";
} else {
std::cout << "error creating thread: " << err << " " << std::strerror(err) << "\n";
}
}