Call function object from doIt function - c++

#include <iostream>
void hello1() {
std::cout << "Hello from normal\n";
}
auto hello2 = [] {
std::cout << "Hello from lamda\n";
};
class hello
{
public:
hello() {}
void operator()(std::string str) {
std::cout << "From functor " << str << std::endl<<std::endl;
}
};
void doIt(void(*f)()) {
f();
}
int main() {
hello1();
hello2();
hello hello3;
hello3("Hello");
doIt(hello1);
doIt(hello2);
doIt(hello3); //How can I do this?
}
I just started learning function objects and I cannot call function object from doIt function
How can I call the last function object with doIt function?
Any help would be appreciated.

Related

C++ : custom vtable implementation does not work

I'm trying to implement a custom vtable to better understand a concept of virtual tables and overriding. For this I have the following 'base' class
#pragma once
#include <iostream>
#include <string>
using namespace std::string_view_literals;
struct vtable;
class IdentityDocument {
public:
IdentityDocument()
: vtable_ptr_(&IdentityDocument::VTABLE),
unique_id_(++unique_id_count_)
{
std::cout << "IdentityDocument::Ctor() : "sv << unique_id_ << std::endl;
}
~IdentityDocument() {
--unique_id_count_;
std::cout << "IdentityDocument::Dtor() : "sv << unique_id_ << std::endl;
}
IdentityDocument(const IdentityDocument& other)
: vtable_ptr_(other.vtable_ptr_),
unique_id_(++unique_id_count_)
{
std::cout << "IdentityDocument::CCtor() : "sv << unique_id_ << std::endl;
}
IdentityDocument& operator=(const IdentityDocument&) = delete;
void PrintID() const {
std::cout << "IdentityDocument::PrintID() : "sv << unique_id_ << std::endl;
}
static void PrintUniqueIDCount() {
std::cout << "unique_id_count_ : "sv << unique_id_count_ << std::endl;
}
int GetID() const {
return unique_id_;
}
private:
vtable* vtable_ptr_ = nullptr;
static int unique_id_count_;
static vtable VTABLE;
int unique_id_;
};
struct vtable
{
void (IdentityDocument::* const PrintID)() const;
vtable (
void (IdentityDocument::* const PrintID)() const
) : PrintID(PrintID) {}
};
int IdentityDocument::unique_id_count_ = 0;
vtable IdentityDocument::VTABLE = {&IdentityDocument::PrintID};
And here is another class that must override PrintId method
#pragma once
#include "identity_document.h"
#include <iostream>
#include <string>
#include <ctime>
using namespace std::string_view_literals;
class Passport {
public:
Passport()
: expiration_date_(GetExpirationDate())
{
IdentityDocument* base_ptr = reinterpret_cast<IdentityDocument*>(this);
vtable* vtable_ptr = reinterpret_cast<vtable*>(base_ptr);
vtable_ptr = &Passport::VTABLE;
std::cout << "Passport::Ctor()"sv << std::endl;
}
Passport(const Passport& other)
: identity_(other.identity_)
, expiration_date_(other.expiration_date_)
{
IdentityDocument* base_ptr = reinterpret_cast<IdentityDocument*>(this);
vtable* vtable_ptr = reinterpret_cast<vtable*>(base_ptr);
vtable_ptr = &Passport::VTABLE;
std::cout << "Passport::CCtor()"sv << std::endl;
}
~Passport() {
std::cout << "Passport::Dtor()"sv << std::endl;
}
void PrintID() const {
std::cout << "Passport::PrintID() : "sv << identity_.GetID();
std::cout << " expiration date : "sv << expiration_date_.tm_mday << "/"sv << expiration_date_.tm_mon << "/"sv
<< expiration_date_.tm_year + 1900 << std::endl;
}
void PrintVisa(const std::string& country) const {
std::cout << "Passport::PrintVisa("sv << country << ") : "sv << identity_.GetID() << std::endl;
}
private:
IdentityDocument identity_;
const struct tm expiration_date_;
static vtable VTABLE;
tm GetExpirationDate() {
time_t t = time(nullptr);
tm exp_date = *localtime(&t);
exp_date.tm_year += 10;
mktime(&exp_date);
return exp_date;
}
};
vtable Passport::VTABLE = {reinterpret_cast<void (IdentityDocument::*)() const>(&Passport::PrintID)};
And a short demo :
int main() {
array<IdentityDocument*, 1> docs = { (IdentityDocument*)(new Passport()) };
for (const auto* doc : docs) {
doc->PrintID();
}
}
Unfortunately, I see that the 'derived' method was not called. Am I using a wrong approach to implement a vtable concept?
Am I using a wrong approach to implement a vtable concept?
Yes. You have not written any code that reads your vtable, and the C++ compiler will not generate any code to read your vtable either.
When you declare a member function virtual, your compiler needs to call that function in a special way. Any call to that function should be looked up in a vtable.
When a member function is not virtual, your compiler knows that it doesn't need to look up the location of the function. It knows which function to call. No lookup needed.
In your code, you have created a vtable, but this line, calling a non-virtual function:
doc->PrintID();
Does not need a vtable, and does not check for one.
doc is an IdentityDocument*, so doc->PrintID() calls IdentityDocument::PrintID(). No lookup required, no lookup happens.
Finally I simplified my solution and got what I wanted :
#include <iostream>
class A;
struct VTable
{
void (*say_hello)(A*);
};
class A
{
public:
A()
{
vtable.say_hello = A::sayHello;
}
void sayHello()
{
vtable.say_hello(this);
}
static void sayHello(A* a)
{
std::cout << "A::sayHello" << std::endl;
}
VTable vtable;
};
class B
{
public:
B()
{
a.vtable.say_hello = B::sayHello;
}
void sayHello()
{
a.vtable.say_hello((A*)this);
}
static void sayHello(A* a)
{
std::cout << "B::sayHello\n" << std::endl;
}
private:
A a;
};
int main()
{
A* a = (A*)(new B);
a->sayHello();
delete a;
}

C++: How to pass a function+arguments as parameter without executing it?

I have 3 algorithms function:
void algo1(int para1, int para2);
void algo2(int para1, int para2);
void algo3(int para1, int para2);
and I want set a timer to test these functions' efficiency
int get_execute_time( void(*f)(int para1, int para2) );
I pass the function as parameter to get_execute_time to avoid abundance, however, the problem is I also need to pass the arguments, which is para1, para2.
so I let timer function change to
get_execute_time( void(*f)(int para1, int para2) ,
int para1, int para2) {
(*f)(para1, para2); // call it
}
and, the code above seems ugly to me, so is there any option to wrap the code and let the code execute later in C++?
so that I can do like this:
// definition
get_execute_time(this_code_will_execute_later) {
this_code_will_execute_later();
};
// usage
get_execute_time(algo1(para1, para2));
Temporary solution: utilize class to implement closure-like thing( inspired from Do we have closures in C++?
class timer {
private:
int para1;
int para2;
public:
timer(int para1, int para2);
operator () (void(*f)(int para1, int para2)) { (*f)(para1, para2) }
}
// thus we can write these following code
timer timer(para1, para2);
std::cout << "run " << timer(algo1) << " ms";
std::cout << "run " << timer(algo2) << " ms"
std::cout << "run " << timer(algo3) << " ms"
So, Do exist better options? Thanks anyway!
You can do this with either std::bind or via a lambda. For example (just one parameter shown for brevity):
#include <iostream>
#include <functional>
void get_execute_time (std::function <void (void)> f)
{
f ();
}
void foo (int i)
{
std::cout << i << '\n';
}
int main()
{
int param = 42;
auto f1 = std::bind (foo, param);
get_execute_time (f1);
++param;
auto f2 = [param] { foo (param); };
get_execute_time (f2);
}
Output:
42
43
Live demo

Call method by string and pass arguments

i search for a way to call a method by its string name.
#include <iostream>
#include <string>
class myClass{
public:
void method1(int run){
std::cout << run << std::endl;
}
void method2(int run){
std::cout << run << std::endl;
}
};
int main(){
myClass mc;
std::string call;
call = "method1";
mc.call(1);
call = "method2";
mc.call(2);
}
But the result, is
‘class Myclass’ has no member named ‘call’
I need response "1" and "2";
EDIT :: Very thank's for your help, i get the next solution (i don't know is good for all cases );
#include <iostream>
#include <string>
class myClass{
public:
void method1(int run){
std::cout << "Loaded method => " << run << std::endl;
}
void method2(int run){
std::cout << "Loaded method => " << run << std::endl;
}
void _loadMethods(int method, int params){
switch(method) {
case 1:
method1(params);
break;
case 2:
method2(params);
break;
default:
break;
}
}
};
int main(){
myClass mc;
std::string method;
method = "method2";
if(method == "method1"){
mc._loadMethods(1, 1);
}
if(method == "method2"){
mc._loadMethods(2, 2);
}
}
Thank's
This is not possible in "raw" C++. But... What you are trying to achieve is some kind of Reflection or Class meta-type information.
You can look at this project: http://www.axelmenzel.de/projects/coding/rttr , use Qt: http://doc.qt.io/qt-5/qmetatype.html#details or google for C++ reflection.

How to use a std::function as a C style callback

How can I use a std::function in a function which expects a C-style callback?
If this is not possible, what is the next best thing?
Example:
// --- some C code I can not change ---
typedef void(*fun)(int);
void register_callback(fun f) {
f(42); // a test
}
// ------------------------------------
#include <functional>
#include <iostream>
void foo(const char* ptr, int v, float x) {
std::cout << ptr << " " << v << " " << x << std::endl;
}
int main() {
std::function<void(int)> myf = std::bind(&foo, "test", std::placeholders::_1, 3.f);
register_callback(myf); // <-- How to do this?
}
In most cases you can't.
But when you store a C style callback in your std::function, you can use the target() member function.
Long answer: sort of. You can write a C function to pass to the API that calls your std::function:
// --- some C code I can not change ---
typedef void(*fun)(int);
void register_callback(fun f) {
f(42); // a test
}
// ------------------------------------
#include <functional>
#include <iostream>
void foo(const char* ptr, int v, float x) {
std::cout << ptr << " " << v << " " << x << std::endl;
}
namespace {
std::function<void(int)> callback;
extern "C" void wrapper(int i) {
callback(i);
}
}
int main() {
callback = std::bind(&foo, "test", std::placeholders::_1, 3.f);
register_callback(wrapper); // <-- How to do this?
}

Overload operator<< for text rendering

I want to create a class which would help me with debugging by providing std::cout or QDebug like functionality using a 3D renderer.
I have the following renderer method which I'm using now
IRenderer::renderText(int posX, int posY, const float* color, const char* text, ...);
// E.g.
int i;
float f;
float color[] = {1, 1, 1, 1};
renderer->renderText(50, 50, color, "Float %f followed by int %i", f, i);
This actually works fine, but I wonder if it's possible to create a class which would allow me to do it like this:
debug() << "My variables: " << i << ", " << "f";
I assume there would be a template function which would build the string to pass to renderText() based on input type, but I'm not quite sure how to implement it.
An alternative to Rob's answer is to include an ostringstream in your custom logger class, and use the destructor to do the logging:
#include <iostream>
#include <sstream>
class MyLogger
{
protected:
std::ostringstream ss;
public:
~MyLogger()
{
std::cout << "Hey ma, I'm a custom logger! " << ss.str();
//renderer->renderText(50, 50, color, ss.str());
}
std::ostringstream& Get()
{
return ss;
}
};
int main()
{
int foo = 12;
bool bar = false;
std::string baz = "hello world";
MyLogger().Get() << foo << bar << baz << std::endl;
// less verbose to use a macro:
#define MY_LOG() MyLogger().Get()
MY_LOG() << baz << bar << foo << std::endl;
return 0;
}
I like to derive my logging class from std::ostream, so I get all of the stream goodness. The trick is to put all of your application-specific code in the associated streambuf class. Consider this working example. To modify it to meed your needs, simply rewrite CLogBuf::sync(), like so:
int sync() {
renderer->renderText(50, 50, color, "%s", str());
str("");
return false;
}
Example:
#include <iostream>
#include <sstream>
class CLogger : public std::ostream {
private:
class CLogBuf : public std::stringbuf {
private:
// or whatever you need for your application
std::string m_marker;
public:
CLogBuf(const std::string& marker) : m_marker(marker) { }
~CLogBuf() { pubsync(); }
int sync() { std::cout << m_marker << ": " << str(); str(""); return !std::cout; }
};
public:
// Other constructors could specify filename, etc
// just remember to pass whatever you need to CLogBuf
CLogger(const std::string& marker) : std::ostream(new CLogBuf(marker)) {}
~CLogger() { delete rdbuf(); }
};
int main()
{
CLogger hi("hello");
CLogger bye("goodbye");
hi << "hello, world" << std::endl;
hi << "Oops, forgot to flush.\n";
bye << "goodbye, cruel world\n" << std::flush;
bye << "Cough, cough.\n";
}