So I have an overloaded templated function that needs to be passed down to a thread. I don't know how to distinguish overloaded functions to a function pointer.
template<typename T>
void DetectChange(T& variable, T& notify) { // must be a thread, else it's useless
T original = variable;
while (true) {
if (variable != original) { // change detected
notify = variable; // send notification
variable = original; // reset to original
}
}
}
template<typename T>
void DetectChange(T& variable, void (* notify)()) { // must be a thread, else it's useless (template, function pointer)
T original = variable;
while (true) {
if (variable != original) { // change detected
notify(); // do notification function
variable = original; // reset to original
}
}
}
int main() {
int x = 3;
void(*function)();
function = &DetectChange; // how to distinguish which overloaded templated function
std::thread detect = std::thread(&function, x, doSomething);
x++; // change variable
return 0;
}
Your problem is that function doesn't match either overload. function is declared taking no arguments but both available overloads take at least two. And the function-pointer type has to match down to references etc.
void (*ptr)(int &, int&) = &DetectChange;
Of course that would fail to compile because int isn't a valid T but it should give you the idea.
Related
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.
Is it possible for the same member function to have different definitions for different objects of that class?
IMPORTANT NOTE: I cannot use a callback like in this solution. (reason explained below example)
Lets say we have this object:
struct object
{
int n;
int m;
void f();
};
Is it possible to have something like:
object a,b;
// and here to define the functions
a.f() {std::cout << n+m;}
b.f() {std::cout << n-m;}
The reason i cannot use a callback is because the function i want to define will be recursive and will overflow. What i am trying to do with this method is to create an immitation of the stack (but all the variables are stored on heap as a double chained list) and so i will call a void (void) function that has no local variables thus increasing the stack depth the function can achieve. Also important to mention is that i want to make a header file with this idea. For further context explination, this is how it should work:
MyHeader.h
template <typename PARAM_TYPE> class HEAP_FUNCTION
{
private:
struct THIS_CALL // ! THIS HAS NOTHING TO DO WITH THE __thiscall CALLING CONVENTION !
{
PARAM_TYPE* PARAM;
THIS_CALL* next_call;
THIS_CALL* prev_call;
};
THIS_CALL* FIRST_CALL;
THIS_CALL* CURRENT_CALL;
public:
HEAP_FUNCTION(PARAM_TYPE* FirstCall)
{
FIRST_CALL = new THIS_CALL;
CURRENT_CALL = FIRST_CALL;
FIRST_CALL->PARAM = *FirstCall;
}
HEAP_FUNCTION(PARAM_TYPE FirstCall)
{
FIRST_CALL = new THIS_CALL;
CURRENT_CALL = FIRST_CALL;
FIRST_CALL->PARAM = FirstCall;
}
~HEAP_FUNCTION()
{
delete FIRST_CALL;
}
void call(void);
};
Source.cpp
// This is the ilustration of the recursive method for calculating
// the 1+2+3+...+n sum.
// The "normal" definition for this function would be:
//
// unsigned long long sum(unsigned long long n)
// {
// if (n == 0) return 0;
// return n + sum(n-1);
// }
//
// The function presented bellow is the equivalent.
struct Param
{
unsigned long long n;
unsigned long long return_value;
}
int main()
{
Param start_value;
start_value.n = 10; // we will calculate 1+2+...+10
HEAP_FUNCTION<Param> Gauss(&start_value);
// We imagine this is where i define call().
// The code written in this definiton works correctly.
Gauss.call()
{
// Test if the function needs to stop further calls.
if(CURRENT_CALL->PARAM->n == 0)
{
CURRENT_CALL->PARAM->return_value = 0;
return;
}
// Prepare the parameters for the next function call.
CURRENT_CALL->next_call = new THIS_CALL;
CURRENT_cALL->next_call->PARAM = new PARAM_TYPE;
CURRENT_CALL->next_call->prev_call = CURRENT_CALL;
CURRENT_CALL->next_call->PARAM->n = CURRENT_CALL->PARAM->n - 1;
// Call the next instance of the function.
CURRENT_CALL = CURRENT_CALL->next_call;
call();
CURRENT_CALL = CURRENT_CALL->prev_call;
// Collect the return value of the callee.
CURRENT_CALL->PARAM->return_value = CURRENT_CALL->PARAM->n + CURRENT_CALL->next_call->PARAM->return_value;
// Delete the space used by the callee.
delete CURRENT_CALL->next_call;
}
// This is the actual call of the function.
Gauss.call();
// The return value is found in the start_value struct.
std::cout << start_value.return_value << std::endl;
return 0;
}
IMPORTANT NOTE: Derivering the entire class will result in a single call() definition for funtions like sum(a, b) and dif(a, b) since they will use the same PARAM struct. (Even though they are not recursive, and the probability of someone using this is very small, this method is good in a bigger program when some of your functions will have a lot of parameters and just placing them on the heap will result in more stack space)
Don't think I understood the question properly, but did you consider function overloading?
I am attempting to bind the first parameter of a variadic function using std::bind and then pass the returned functor to the connect() function of a boost::signals2::signal. The process works fine as long as the variadic function is not a member function. This is what I would like to be able to do:
class test {
public:
test() {}
void call_var_callback(string const& func, ...) {
va_list args;
va_start(args, func);
std::cout << "Calling variadic function: " << func << std::endl;
}
};
test t;
void register_callback2(std::map<string, boost::any>& sig_table,
string func, string event) {
auto event_entry = sig_table.find(event);
if (event_entry != sig_table.end()) {
if (event == "event1") {
auto sig = boost::any_cast<signal<void (void)>*>(sig_table["event1"]);
sig->connect(std::bind(&test::call_var_callback, &t, std::cref(func)));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
} else {
std::cout << "No such event exists!" << std::endl;
}
}
int main( void ) {
// define events
signal<void (void)> event1;
signal<void (char const*)> event2;
signal<void (int, char const*)> event3;
// intialize event / signal lookup table
std::map<string, boost::any> sig_tbl;
sig_tbl["event1"] = &event1;
sig_tbl["event2"] = &event2;
sig_tbl["event3"] = &event3;
// connect the signals
register_callback2(sig_tbl, "func1", "event1");
register_callback2(sig_tbl, "func2", "event2");
register_callback2(sig_tbl, "func3", "event3");
// call the signals
for (int i = 1000; i > 0; --i) {
(*boost::any_cast<signal<void (void)>*>(sig_tbl["event1"]))();
(*boost::any_cast<signal<void (char const*)>*>(sig_tbl["event2"]))("0xBAAD");
(*boost::any_cast<signal<void (int, char const*)>*>(sig_tbl["event3"]))(5, "0xBEEF");
}
}
When I compile I get an error that states there is "no match for call to ..." Where ... is the filled in templated type of the call to bind. If I move the definition of call_var_callback() outside the scope of the 'test' object, everything works. However, in my real code base I need the bound function to be a member of a class because it carries state along with it.
Thank you in advance for your consideration and assistance.
When you bind member functions, you don't take the address of the object. In your code :
sig->connect(std::bind(&test::call_var_callback, &t, std::cref(func)));
the &t is wrong, it should be a plain t
bind supports 2 main ways of binding the object: You can
pass an object itself or
a pointer to object (as well as a shared pointer instead of a raw pointer)
I am not sure whether the following is possible. Can someone give an equivalent for this requirement?
if(dimension==2)
function = function2D();
else if(dimension==3)
function = function3D();
for(....) {
function();
}
It is possible, assuming two things:
Both function2D() and function3D() have the same signature and return type.
function is a function pointer, with the same return type and parameters as both function2D and function3D.
The technique you are exploring is very similar to the one used in constructing a jump table. You have a function pointer, which you assign (and call through) at run-time based on run-time conditions.
Here is an example:
int function2D()
{
// ...
}
int function3D()
{
// ...
}
int main()
{
int (*function)(); // Declaration of a pointer named 'function', which is a function pointer. The pointer points to a function returning an 'int' and takes no parameters.
// ...
if(dimension==2)
function = function2D; // note no parens here. We want the address of the function -- not to call the function
else if(dimension==3)
function = function3D;
for (...)
{
function();
}
}
You can use function pointers.
There's a tutorial here but basically what you do is declare it like this:
void (*foo)(int);
where the function has one integer argument.
Then you call it like this:
void my_int_func(int x)
{
printf( "%d\n", x );
}
int main()
{
void (*foo)(int);
foo = &my_int_func;
/* call my_int_func (note that you do not need to write (*foo)(2) ) */
foo( 2 );
/* but if you want to, you may */
(*foo)( 2 );
return 0;
}
So as long as your functions have the same number and type of argument you should be able to do what you want.
Since this is also tagged C++, you can use std::function if you have access to C++11, or std::tr1::function if your compiler supports C++98/03 and TR1.
int function2d();
int function3D();
int main() {
std::function<int (void)> f; // replace this with the signature you require.
if (dimension == 2)
f = function2D;
else if (dimension == 3)
f = function3D;
int result = f(); // Call the function.
}
As mentioned in the other answers, make sure your functions have the same signature and all will be well.
If your compiler doesn't offer std::function or std::tr1::function, there's always the boost library.
Since you choose C++
Here's with std::function example in C++11
#include <functional>
#include <iostream>
int function2D( void )
{
// ...
}
int function3D( void )
{
// ...
}
int main()
{
std::function<int(void)> fun = function2D;
fun();
}
To avoid code duplication, I'm tring to pass pointers to functions as arguments of a static method.
I have a class (Geo) with only static methods. One of this methods (+++Geo::traceRay(+++)) should just display(Geo::display(+++)) few things, then return an int.
Another class (Las) needs to use the Geo::traceRay(+++) method, but should display(Las::display(+++)) someting else.
So I try to pass a pointer to function argument to the Geo::traceRay(+++, pointer to function) method. the pointed functon will the right "display()" method.
Up to now, passing the first pointer to display() is not an issue, but I can't find how to do it with the second one.
class Geo
{
public:
static bool display(int pix);
static int traceRay(int start, int end, bool (*func)(int) = &Geo::display); // no issue with this default parameter
};
class Las
{
public:
bool display(int pix);
void run();
};
int Geo::traceRay(int start, int end, bool (*func)(int))
{
for (int i = start; i < end ; ++i )
{
if((*func)(i)) return i;
}
return end;
}
bool Geo::display(int pix)
{
cout << pix*100 << endl;
return false;
}
bool Las::display(int pix)
{
cout << pix << endl;
if (pix == 6) return true;
return false;
}
void Las::run()
{
bool (Las::*myPointerToFunc)(int) = &display; // I can just use display as a non member class, but it should stay a member
Geo::traceRay(0,10, myPointerToFunc); // issue here!
}
int main()
{
Geo::traceRay(0,10); // use the "normal display" = the default one// OK
Las myLas;
myLas.run();
return 0;
}
You can't pass a member function pointer as a function pointer. I presume making Las::display static is not an option. In that case, I would suggest taking a std::function and using std::bind to bind the current instance:
static int traceRay(int start, int end, std::function<bool(int)> func = &Geo::display);
...
Geo::traceRay(0,10, std::bind(&Las::display, this, std::placeholders::_1));
Also, in both cases, you can call func by:
func(i);
No need to dereference it first.
What Chris suggests is great if that's as far as it goes.
Another approach to this, which would be beneficial if you have several shared functions like that, would be to use an interface (with a virtual method Display(+++)) with two implementations, put an instance of the implementation in question in each of Geo and Las (or Las could directly implement the interface). Then traceRay takes a reference to the interface base class and calls the display method on it.