Method of object as method argument of another class in c++ [duplicate] - c++

This question already has answers here:
Function pointer to member function
(8 answers)
Closed 10 months ago.
I have an istance of a class A, that has some methods like:
class A
{
...
public:
bool DoOperation_one(Mytype* pSomeValue);
bool DoOperation_two(Mytype* pSomeValue);
...
bool DoOperation_th(Mytype* pSomeValue);
...
}
Another class, class B, has a pointer to A class and a method BMethod.
Class B
{
...
A* myPtrA;
...
bool BMethod(...); // arguments have to be defined
}
Is it possible to pass to BMethod, methods of A class instance as argument? I will try to be more clear with the follow pseudocode. In same place in class B i call BMethod with myPtrA method as argument (with parameters). I don't want to execute the myPtrA->DoOperation_two(somevalue) at calling time, but only in the BMethod (if statement):
...
bool bVal = BMethod(myPtrA->DoOperation_two(somevalue))
...
bool B::BMethod("valid signature" myFunction)
{
bool bfun=false;
if (myFunction)
{
do_something....
}
return bfun;
}
My goal is to call BMethod argument (DoOperation_one, DoOperation_two or DoOperation_th) in the body of BMethod only. I have been used template, but DoOperation_XXX is executed at calling time.
....
bool bVal = BMethod(myPtrA->DoOperation_two(somevalue));
or
bool bVal = BMethod(myPtrA->DoOperation_one(somevalue));
...
template <typename FunctionT>
bool BMethod(FunctionT myFunc)
{
bool bfun=false;
bool breturn = false;
while (!bfun)
{
if (myFunc)
{
bfun=true;
breturn = some_other_operation();
}
}
return breturn ;
}
Moreover, myFunc contains result of myPtrA->DoOperation_one(somevalue), and doesn't change in the while statement because it has executed at calling time.
Is there any other approach/solution?

You can pass a member function pointer but then you'll need an A instance to call it and a Mytype* to be passed as parameter:
struct Mytype {};
struct A {
bool DoOperation_one(Mytype* pSomeValue) { return true;}
bool DoOperation_two(Mytype* pSomeValue) { return true;}
bool DoOperation_th(Mytype* pSomeValue) { return true; }
};
struct B {
A a;
template <typename F>
bool BMethod(F f,Mytype* mt) {
bool bfun=false;
bool breturn = false;
while (!bfun) {
if ((a.*f)(mt))
{
bfun=true;
breturn = true;//some_other_operation();
}
}
return breturn ;
}
};
int main() {
Mytype mt;
B b;
b.BMethod(&A::DoOperation_one,&mt);
}
Instead of making BMethod a template, I could have spelled out the type explcitly, it is bool (A::*)(Mytype*). The syntax to call a member function pointer is a little clunky. If a is a pointer to A (like in your code) then it is (a.->f)(mt).
Note that this only makes sense if the value returned from A::DoOperation_xyz changes while B::BMethod is executing. For example when multiple threads are involved. If thats the case you need to be careful with synchronizing access to shared data to avoid data races. If this isnt multi-threaded, I see no reason to make it complicated and BMethod can simply be bool BMethod(bool x).

Related

Is it possible to change behavior of function based on scope?

I would like to create something similar to rust unsafe scope in C++.
The idea is that I have some functions performing number of checks. For example:
void check() {
if (...)
throw exception(...);
}
void foo() {
check();
// do some work
}
Now, I want to be able to call function foo() with or (in different context) without performing those checks. Ideally it would look like this:
foo(); // call foo and perform checks
unsafe {
foo(); // call foo without checks
}
My question is, is it possible to achieve something like this in compile time? Is it possible to somehow check (or act differently) from check function in what scope it is called?
I came up only with a runtime solution: to wrap it in some lambda:
unsafe([&] {
foo();
});
where unsafe is implemented as follows:
void unsafe(std::function<void()> f)
{
thread_local_flag = unsafe;
f();
thread_local_flag = safe;
}
check() function would just check for the thread_local flag and perform checks only when it is set to safe.
🤔
namespace detail_unsafe {
thread_local int current_depth;
struct unsafe_guard {
unsafe_guard() { ++current_depth; }
~unsafe_guard() { --current_depth; }
unsafe_guard(unsafe_guard const &) = delete;
unsafe_guard &operator = (unsafe_guard const &) = delete;
};
}
#define unsafe \
if(::detail_unsafe::unsafe_guard _ug; false) {} else
bool currently_unsafe() {
return detail_unsafe::current_depth > 0;
}
See it live on Coliru. Also, please don't actually define unsafe as a macro...
is it possible to achieve something like this in compile time?
Not the way you presented. Making foo a template function might give you equivalent results, though:
enum class CallType // find a better name yourself...
{
SAFE,
UNSAFE,
};
template <CallType Type = CallType::SAFE>
void foo()
{
if constexpr(Type != CallType::UNSAFE)
{
if (...)
throw ...;
}
// do some work
}
You might call it like:
foo();
foo<CallType::UNSAFE>();
Disliking templates?
Simple approach (thanks, #VTT):
void check(); // no template any more
void foo_unsafe()
{
// do some work
}
inline void foo()
{
check();
foo_unsafe();
}
Or selecting via parameter (this pattern exists in standard library, too):
struct Unsafe
{
};
inline Unsafe unsafe;
void check();
void foo(Unsafe)
{
// do some work
}
inline void foo()
{
check();
foo(unsafe);
}
Edit:
Well, in the example I presented I could do that, but in general, I can call some other function bar inside unsafe which in turn calls foo. And I don't want to specialize bar and possible other methods.
Unter this constraint, the template variant might be the closest you can get to at compile time; you don't have to specialise all the functions, but you'd need to make templates from:
template <CallType Type = CallType::SAFE>
void bar()
{
// do some other work
foo<Type>(); // just call with template parameter
// yet some further work
}
I would simply use a RAII type to toggle the unsafe flag inside a scope as such:
thread_local bool unsafe_flag = false;
/// RAII Type that toggles the flag on while it's alive
/// Possibly add a reference counter so it can be used nested
struct unsafe_scope
{
constexpr unsafe_scope() { unsafe_flag = true; }
~unsafe_scope() { unsafe_flag = false; }
};
/// Gets a value from a pointer
int get_value(int* ptr)
{
if ( unsafe_flag )
{
if ( ptr == nullptr ) { return 0; }
}
return *ptr;
}
int main()
{
int* x = nullptr;
//return get_value(x); // Doesn't perform the check
{
unsafe_scope cur_scope;
return get_value(x); // Performs the check
}
}
In order to make it nested I would add a reference counter like this:
/// RAII Type that toggles the flag on while it's alive
struct unsafe_scope
{
thread_local static size_t ref_count;
constexpr unsafe_scope()
{
unsafe_flag = true;
ref_count++;
}
~unsafe_scope()
{
ref_count--;
if ( ref_count == 0 ) { unsafe_flag = false; }
}
};
/// In source file
thread_local size_t unsafe_scope::ref_count = 0;
The ref_count doesn't need to be atomic since it's thread_local
Now I don't think there's a way to achieve the syntax you wanted with the unsafe before the scope, but if you put it right after the scope as such it should be about the same:
{ unsafe_scope cur_scope;
return get_value(x); // Performs the check
}
Edit:
I've now noticed Quentin's answer is also a RAII type, just with slightly different semantics, instead of having a global thread_local flag a function just returns if the reference counter is bigger than 0. Also the macro achieves the exact syntax you wanted, although it's also possible with this unsafe_scope by modifying his macro like this:
#define unsafe\
if (unsafe_scope cur_scope; false) {} else
His method uses C++17's if initializer, which lets you initiates a variable in the if statement, but the variable is still initialized in the else block, so it only gets destroyed after the else scope if over.

Modifying a pointer pointer field from a method

I'm trying to modify a bool field in a method. The method accepts a pointer pointer bool, but can't seem to figure it out how to do this correctly.
This is a basic example of something similar I want to do:
class WarningManager {
bool seenWarningA;
void updateWarnings() {
pushWarning(&seenWarningA)
}
void pushWarning(bool ** warning) {
**warning = true;
}
}
This code example errors (sending bool* but needs to be bool**) and I've tried other ways with no luck. Can't find any online examples but maybe I'm searching for the wrong terms. What is the right way to do this?
Since you have a class, no parameters are required.
class WarningManager {
bool seenWarningA;
void updateWarnings() {
pushWarning()
}
void pushWarning() {
seenWarningA = true;
}
}
Using references rather than pointers is more elegant.
class WarningManager {
bool seenWarningA;
void updateWarnings() {
pushWarning(seenWarningA)
}
void pushWarning(bool & warning) {
warning = true;
}
}
If you want to use pointers, the & operator just gives single pointer rather than a double point:
class WarningManager {
bool seenWarningA;
void updateWarnings() {
pushWarning(&seenWarningA)
}
void pushWarning(bool * warning) {
*warning = true;
}
}
You appear to be trying to pass an argument of bool* into a function that takes bool**. Remove one of the layers of indirection from the parameter list, or add one to the value you're passing in. Either should work.
Two mistakes:
First- your declaration of pushWarning is with parameter of type bool**, and you are trying to send bool*.
Second- you can simply use reference:
using namespace std;
class WarningManager {
public:
bool seenWarningA;
void updateWarnings() {
pushWarning(seenWarningA);
}
void pushWarning(bool &warning) { // You can simply use refference instead of pointer to pointer, or pointer at all..
warning = true;
}
};
int main()
{
WarningManager w;
w.seenWarningA = false;
w.updateWarnings();
cout << w.seenWarningA; // Prints 1
return 0;
}

Storage of function pointer in polymorphic class without explicit template specialization

I am trying to create a helper class to abstract invoking function pointers. With feedback from others on SO, I am using a polymorphic class to achieve this (shown below). Templates are also used to reduce code duplication.
typedef void(*PFNFOO1) (int);
typedef void(*PFNFOO2) (double);
typedef void(*PFNBAR1) (long);
typedef void(*PFNBAR2) (float);
typedef struct FOO_TABLE
{
PFNFOO1 pfnFoo1;
PFNFOO2 pfnFoo2;
} FOO_TABLE;
typedef struct BAR_TABLE
{
PFNBAR1 pfnBar1;
PFNBAR2 pfnBar2;
} BAR_TABLE;
enum TABLE_TYPE
{
TYPE_FOO = 0,
TYPE_BAR = 1,
};
template <typename T>
class FooBarImpl : public FooBarBase
{
public:
// GetFunc is created to centralize needed validation before function is invoked
void* GetFunc(size_t funcOffset)
{
// do some validation
return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
}
void* GetpfnFoo1() { return GetFunc(offsetof(T, pfnFoo1)); }
void* GetpfnFoo2() { return GetFunc(offsetof(T, pfnFoo2)); }
void* GetpfnBar1() { return GetFunc(offsetof(T, pfnBar1)); }
void* GetpfnBar2() { return GetFunc(offsetof(T, pfnBar2)); }
T* m_FooBarTable;
};
class FooBarBase
{
public:
static FooBarBase* CreateFooBar(TABLE_TYPE tableType)
{
switch(tableType)
{
case (TYPE_FOO) :
{
return new FooBarImpl<FOO_TABLE>();
}
break;
case (TYPE_BAR) :
{
return new FooBarImpl<BAR_TABLE>();
}
break;
}
}
virtual void* GetpfnFoo1() = 0;
virtual void* GetpfnFoo2() = 0;
virtual void* GetpfnBar1() = 0;
virtual void* GetpfnBar2() = 0;
};
int _tmain(int argc, _TCHAR* argv[])
{
{
FooBarBase *pFooBar = FooBarBase::CreateFooBar(TYPE_FOO);
// Initialize Foo table
auto p = reinterpret_cast<PFNFOO1>(pFooBar->GetpfnFoo1());
int parameter = 1;
p(parameter);
}
{
FooBarBase *pFooBar = FooBarBase::CreateFooBar(TYPE_FOO);
// Initialize Bar table
auto p = reinterpret_cast<PFNBAR2>(pFooBar->GetpfnBar2());
float parameter = 1.0f;
p(parameter);
}
return 0;
}
This is currently giving me complication errors as "C2039: 'pfnBar1' : is not a member of 'FOO_TABLE'" which makes sense because one of the implicit template specialization will try to do "offsetof(FOO_TABLE, pfnBar1)," which isn't allowed. I have two questions. First, I am wondering what's the best way to address this error. I think I can possibly address this by providing explicit template specializations for FooBarImpl and FooBarImpl, but I'd like to avoid doing that because it means that if I were to add a new table type later, I'd have to add another specialization. Also, it increases code duplication. Therefore, if there's a way to fix this issue without explicit template specialization, please let m know.
For my second question, if explicit template specialization cannot be avoided, I have also tried this:
class FooBarBase;
template <typename T>
class FooBarImpl : public FooBarBase
{
};
template <>
class FooBarImpl<FOO_TABLE> : public FooBarBase
{
public:
typedef FOO_TABLE T;
// GetFunc is created to centralize needed validation before function is invoked
void* GetFunc(size_t funcOffset)
{
// do some validation
return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
}
void* GetpfnFoo1() { return GetFunc(offsetof(T, pfnFoo1)); }
void* GetpfnFoo2() { return GetFunc(offsetof(T, pfnFoo2)); }
T* m_FooBarTable;
};
template<>
class FooBarImpl<BAR_TABLE> : public FooBarBase
{
public:
typedef BAR_TABLE T;
// GetFunc is created to centralize needed validation before function is invoked
void* GetFunc(size_t funcOffset)
{
// do some validation
return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
}
void* GetpfnBar1() { return GetFunc(offsetof(T, pfnBar1)); }
void* GetpfnBar2() { return GetFunc(offsetof(T, pfnBar2)); }
T* m_FooBarTable;
};
But for some reason, I keep getting this error "error C2504: 'FooBarBase' : base class undefined" even if it was working fine before I specialized the templates.
If anyone has ideas about these 2 questions, I'd really appreciate your feedback. Thanks.

std::vector of std::functions find

I have a vector populated with callback functions and I would like to check whether callback to the function already exists prior to adding it. I don't know whether it will even work bu so far it doesn't even compile.
vector<std::function<void(void*)>> _callbacks;
void Event::RegisterCallback(std::function<void(void*)> callback)
{
if (callback == NULL)
return;
vector<std::function<void(void*)>>::iterator it = std::find(_callbacks.begin(), _callbacks.end(), callback);
if (it == _callbacks.end())
{
_callbacks.push_back(callback);
}
else
{
//print error
throw;
}
}
This gives a compile error:
"Overload resolution selected deleted operator '=='" in alorithm(805). This is related to the find function call.
How do I get this to work and is it even going to compare function calls to the same method properly?
Thanks
As noted in the comments the simplest solution is to use default C-style function pointers as they support == operator in opposite to C++11 function which does not.
using func_type = void(*)();
vector<func_type> _callbacks;
void Event::RegisterCallback(func_type callback)
{
if (callback == nullptr)
return;
auto it = std::find(_callbacks.begin(), _callbacks.end(), callback);
if (it == _callbacks.end()) {
_callbacks.push_back(callback);
}
else {
throw;
}
}
void f() {};
void g() {};
/*
evt.RegisterCallback(f); // works fine
evt.RegisterCallback(g); // works fine
evt.RegisterCallback(f); // throws exception
*/
If you don't like this approach you can write your own function-pointer class with support of equality operator.
Another solution is to have a class with a std::function member and another comperable member, and then overloading the () to get the std::function parameter and call it with the parameter, and the == operator to compeare the class using the comperable member.
CompareableFunction.h:
class CompareableFunction
{
public:
CompareableFunction(int nId, std::function<void(parameter)> handler);
~CompareableFunction();
void operator()(parameter param);
bool operator== (CompareableFunction compareableFunc);
private:
std::function<void(parameter)> m_handler;
int m_nId;
};
CompareableFunction.cpp:
CompareableFunction::CompareableFunction(int nId, std::function<void(parameter)> handler)
{
m_nId = nId;
m_handler = handler;
}
CompareableFunction::~CompareableFunction()
{
}
void CompareableFunction::operator()(parameter param)
{
return m_handler(param);
}
bool CompareableFunction::operator==(CompareableFunction compareableFunc)
{
return (m_nId == compareableFunc.m_nId);
}
EDIT: you can convert the std::function to a C-style function pointer and use it to compare. example to a conversion is here: http://www.cplusplus.com/forum/general/63552/

VC++ "Re-use" a function?

How can I re-use a function?
Okay lets say I have this "main" function below:
bool A = false;
bool B = true;
void MainFunction(bool Whatever) {
if(!Whatever) {
A = true;
if(A) {
B = false;
} else if(!A) {
B = true;
}
}
}
Now I want to make a new function using the MainFunction, something like this:
MainFunction ANewFunction(false);
MainFunction AnotherNewFunction(true);
Obviously that won't work, so is there any way to "re-use" a function as a different function?
You're welcome to have one function call another. For example:
void ANewFunction() {
MainFunction(false);
}
void AnotherNewFunction() {
MainFunction(true);
}
You can even get fancy:
#include <functional>
auto ANewFunction = std::bind(&MainFunction, false);
auto AnotherNewFunction = std::bind(&MainFunction, true);
Either way, you can call ANewFunction or AnotherNewFunction, and MainFunction will get called with the given argument. (In the latter case, they're not really functions anymore. They're called function objects, or functors, but you cal still call them just like ordinary functions: ANewFunction().)
You can't "re-use" functions, at least not in the way I understand your question.
But you can create a new function that calls the original function and then does some additional work of its own. For example:
void PrevFunction(int one)
{
int i = one;
// do whatever
}
void NewFunction(int one)
{
PrevFunction(one);
// do new stuff
// ...
}
You could also define a class, and then use inheritance and virtual functions to modify the behavior of a particular set of functions from the base class.
typedef int (*function_t)(int); // new type - defines function type - address of function
// your function, PrevFunction is simply variable holding address of the function:
int PrevFunction(int one) { return one; }
// new variable of type function_t initialized by PrevFunction address:
function_t NewFunction = PrevFunction;
//And finally we can use either PrevFunction or NewFunction - they point to the same function body:
int a = PrevFunction(1); // a == 1
int b = NewFunction(2); // a == 2
Simply call MainFunction from your other function?
void ANewFunction()
{
MainFunction(false);
}
void AnotherNewFunction()
{
MainFunction(true);
}
If your question is how do you make AnotherNewFunction refer to a different A and B than ANewFunction, the answer is you can't, at least not without help from MainFunction. You can, however, update MainFunction:
void MainFunction(bool Whatever, bool& A, bool& B) {
if(!Whatever) {
A = true;
if(A) {
B = false;
} else if(!A) {
B = true;
}
}
}
bool A1 = false;
bool B1 = true;
void ANewFunction()
{
MainFunction(false, A1, B1);
}
bool A2 = false;
bool B2 = true;
void AnotherNewFunction()
{
MainFunction(true, A2, B2);
}
Another new-fangled solution, using lambda's:
auto ANewFunction = [](){ MainFunction(false); }
auto AnotherNewFunction = [](){ MainFunction(true); }