Inject additional data in a method - c++

I am adding the new module in some large library. All methods here are implemented as static. Let me briefly describe the simplified model:
typedef std::vector<double> TData;
double test ( const TData &arg ) { return arg ( 0 ) * sin ( arg ( 1 ) + ...;}
double ( * p_test ) ( const TData> &arg) = &test;
class A
{
public:
static T f1 (TData &input) {
.... //some computations
B::f2 (p_test);
}
};
Inside f1() some computations are performed and a static method B::f2 is called. The f2 method is implemented by another author and represents some simulation algorithm (example here is simplified).
class B
{
public:
static double f2 (double ( * p_test ) ( const TData &arg ) )
{
//difficult algorithm working p_test many times
double res = p_test(arg);
}
};
The f2 method has a pointer to some weight function (here p_test). But in my case some additional parameters computed in f1 for test() methods are required
double test ( const TData &arg, const TData &arg2, char *arg3.... ) { }
How to inject these parameters into test() (and so to f2) to avoid changing the source code of the f2 methods (that is not trivial), redesign of the library and without dirty hacks :-) ?
The most simple step is to override f2
static double f2 (double ( * p_test ) ( const TData &arg ), const TData &arg2, char *arg3.... )
But what to do later? Consider, that methods are static, so there will be problems with objects.
Updated question
Is it possible to make a pointer to a function dependent on some template parameter or do something like that
if (condition) res = p_test(arg);
else res = p_test2(arg, arg2, arg3);

without dirty hacks
Not gonna happen. If you can't modify the source of a function taking a function pointer, you'll have to use an exception vomit to gain the extra arguments. If you had a C++11 compiler (that does not exist yet) which supports thread_local, it's theoretically possible to do something better, or you could use OS-specific TLS. But as of right now, the only portable solution is an exception vomit.
void f(void(*fp)()) { fp(); }
void mah_func() {
try {
throw;
} catch(my_class* m) {
m->func();
}
}
int main() {
my_class m;
try {
throw &m;
} catch(my_class* p) {
f(mah_func);
}
}
Alternatively, in your scenario, modifying f2 doesn't seem to be impossible, only difficult. However, the difficulty of altering it to take a std::function<double(const TData&)> would be very low- all you'd have to do is change the argument type, thanks to operator overloading. It should be a very simple change for even a complex function, as you're only changing the type of the function parameter, all the call sites will still work, etc. Then you can pass a proper function object made through bind or a lambda or somesuch.

"avoid changing", well that's a bit difficult.
however, you can use a static variable to pass arguments across calls of functions that don't pass the arguments.
remember that if there is more than one thread using those function, you need to either use thread local storage (which is what i recommend for that) or else ensure proper mutual exclusion for use of those variables, where in the case of a single variable shared between all the threads means exclusion all the way down the call chain. but do use thread local storage if threading is a problem. and if no threading problem, well, no problem! :-)

Related

is there a way to store a generic templated function pointer?

The Goal:
decide during runtime which templated function to use and then use it later without needing the type information.
A Partial Solution:
for functions where the parameter itself is not templated we can do:
int (*func_ptr)(void*) = &my_templated_func<type_a,type_b>;
this line of code can be modified for use in an if statement with different types for type_a and type_b thus giving us a templated function whose types are determined during runtime:
int (*func_ptr)(void*) = NULL;
if (/* case 1*/)
func_ptr = &my_templated_func<int, float>;
else
func_ptr = &my_templated_func<float, float>;
The Remaining Problem:
How do I do this when the parameter is a templated pointer?
for example, this is something along the lines of what I would like to do:
int (*func_ptr)(templated_struct<type_a,type_b>*); // This won't work cause I don't know type_a or type_b yet
if (/* case 1 */) {
func_ptr = &my_templated_func<int,float>;
arg = calloc(sizeof(templated_struct<int,float>, 1);
}
else {
func_ptr = &my_templated_func<float,float>;
arg = calloc(sizeof(templated_struct<float,float>, 1);
}
func_ptr(arg);
except I would like type_a, and type_b to be determined during runtime. I see to parts to the problem.
What is the function pointers type?
How do I call this function?
I think I have the answer for (2): simply cast the parameter to void* and the template function should do an implicit cast using the function definition (lease correct me if this won't work as I think it will).
(1) is where I am getting stuck since the function pointer must include the parameter types. This is different from the partial solution because for the function pointer definition we were able to "ignore" the template aspect of the function since all we really need is the address of the function.
Alternatively there might be a much better way to accomplish my goal and if so I am all ears.
Thanks to the answer by #Jeffrey I was able to come up with this short example of what I am trying to accomplish:
template <typename A, typename B>
struct args_st {
A argA;
B argB;
}
template<typename A, typename B>
void f(struct args_st<A,B> *args) {}
template<typename A, typename B>
void g(struct args_st<A,B> *args) {}
int someFunction() {
void *args;
// someType needs to know that an args_st struct is going to be passed
// in but doesn't need to know the type of A or B those are compiled
// into the function and with this code, A and B are guaranteed to match
// between the function and argument.
someType func_ptr;
if (/* some runtime condition */) {
args = calloc(sizeof(struct args_st<int,float>), 1);
f((struct args_st<int,float> *) args); // this works
func_ptr = &g<int,float>; // func_ptr should know that it takes an argument of struct args_st<int,float>
}
else {
args = calloc(sizeof(struct args_st<float,float>), 1);
f((struct args_st<float,float> *) args); // this also works
func_ptr = &g<float,float>; // func_ptr should know that it takes an argument of struct args_st<float,float>
}
/* other code that does stuff with args */
// note that I could do another if statement here to decide which
// version of g to use (like I did for f) I am just trying to figure out
// a way to avoid that because the if statement could have a lot of
// different cases similarly I would like to be able to just write one
// line of code that calls f because that could eliminate many lines of
// (sort of) duplicate code
func_ptr(args);
return 0; // Arbitrary value
}
Can't you use a std::function, and use lambdas to capture everything you need? It doesn't appear that your functions take parameters, so this would work.
ie
std::function<void()> callIt;
if(/*case 1*/)
{
callIt = [](){ myTemplatedFunction<int, int>(); }
}
else
{
callIt = []() {myTemplatedFunction<float, float>(); }
}
callIt();
If I understand correctly, What you want to do boils down to:
template<typename T>
void f(T)
{
}
int somewhere()
{
someType func_ptr;
int arg = 0;
if (/* something known at runtime */)
{
func_ptr = &f<float>;
}
else
{
func_ptr = &f<int>;
}
func_ptr(arg);
}
You cannot do that in C++. C++ is statically typed, the template types are all resolved at compile time. If a construct allowed you to do this, the compiler could not know which templates must be instanciated with which types.
The alternatives are:
inheritance for runtime polymorphism
C-style void* everywhere if you want to deal yourself with the underlying types
Edit:
Reading the edited question:
func_ptr should know that it takes an argument of struct args_st<float,float>
func_ptr should know that it takes an argument of struct args_st<int,float>
Those are incompatible. The way this is done in C++ is by typing func_ptr accordingly to the types it takes. It cannot be both/all/any.
If there existed a type for func_ptr so that it could take arguments of arbitrary types, then you could pass it around between functions and compilation units and your language would suddenly not be statically typed. You'd end up with Python ;-p
Maybe you want something like this:
#include <iostream>
template <typename T>
void foo(const T& t) {
std::cout << "foo";
}
template <typename T>
void bar(const T& t) {
std::cout << "bar";
}
template <typename T>
using f_ptr = void (*)(const T&);
int main() {
f_ptr<int> a = &bar<int>;
f_ptr<double> b = &foo<double>;
a(1);
b(4.2);
}
Functions taking different parameters are of different type, hence you cannot have a f_ptr<int> point to bar<double>. Otherwise, functions you get from instantiating a function template can be stored in function pointers just like other functions, eg you can have a f_ptr<int> holding either &foo<int> or &bar<int>.
Disclaimer: I have already provided an answer that directly addresses the question. In this answer, I would like to side-step the question and render it moot.
As a rule of thumb, the following code structure is an inferior design in most procedural languages (not just C++).
if ( conditionA ) {
// Do task 1A
}
else {
// Do task 1B
}
// Do common tasks
if ( conditionA ) {
// Do task 2A
}
else {
// Do task 2B
}
You seem to have recognized the drawbacks in this design, as you are trying to eliminate the need for a second if-else in someFunction(). However, your solution is not as clean as it could be.
It is usually better (for code readability and maintainability) to move the common tasks to a separate function, rather than trying to do everything in one function. This gives a code structure more like the following, where the common tasks have been moved to the function foo().
if ( conditionA ) {
// Do task 1A
foo( /* arguments might be needed */ );
// Do task 2A
}
else {
// Do task 1B
foo( /* arguments might be needed */ );
// Do task 2B
}
As a demonstration of the utility of this rule of thumb, let's apply it to someFunction(). ... and eliminate the need for dynamic memory allocation ... and a bit of cleanup ... unfortunately, addressing that nasty void* is out-of-scope ... I'll leave it up to the reader to evaluate the end result. The one feature I will point out is that there is no longer a reason to consider storing a "generic templated function pointer", rendering the asked question moot.
// Ideally, the parameter's type would not be `void*`.
// I leave that for a future refinement.
void foo(void * args) {
/* other code that does stuff with args */
}
int someFunction(bool condition) {
if (/* some runtime condition */) {
args_st<int,float> args;
foo(&args);
f(&args); // Next step: pass by reference instead of passing a pointer
}
else {
args_st<float,float> args;
foo(&args);
f(&args); // Next step: pass by reference instead of passing a pointer
}
return 0;
}
Your choice of manual memory management and over-use of the keyword struct suggests you come from a C background and have not yet really converted to C++ programming. As a result, there are many areas for improvement, and you might find that your current approach should be tossed. However, that is a future step. There is a learning process involved, and incremental improvements to your current code is one way to get there.
First, I'd like to get rid of the C-style memory management. Most of the time, using calloc in C++ code is wrong. Let's replace the raw pointer with a smart pointer. A shared_ptr looks like it will help the process along.
// Instead of a raw pointer to void, use a smart pointer to void.
std::shared_ptr<void> args;
// Use C++ memory management, not calloc.
args = std::make_shared<args_st<int,float>>();
// or
args = std::make_shared<args_st<float,float>>();
This is still not great, as it still uses a pointer to void, which is rarely needed in C++ code unless interfacing with a library written in C. It is, though, an improvement. One side effect of using a pointer to void is the need for casts to get back to the original type. This should be avoided. I can address this in your code by defining correctly-typed variables inside the if statement. The args variable will still be used to hold your pointer once the correctly-typed variables go out of scope.
More improvements along this vein can come later.
The key improvement I would make is to use the functional std::function instead of a function pointer. A std::function is a generalization of a function pointer, able to do more albeit with more overhead. The overhead is warranted here in the interest of robust code.
An advantage of std::function is that the parameter to g() does not need to be known by the code that invokes the std::function. The old style of doing this was std::bind, but lambdas provide a more readable approach. Not only do you not have to worry about the type of args when it comes time to call your function, you don't even need to worry about args.
int someFunction() {
// Use a smart pointer so you do not have to worry about releasing the memory.
std::shared_ptr<void> args;
// Use a functional as a more convenient alternative to a function pointer.
// Note the lack of parameters (nothing inside the parentheses).
std::function<void()> func;
if ( /* some runtime condition */ ) {
// Start with a pointer to something other than void.
auto real_args = std::make_shared<args_st<int,float>>();
// An immediate function call:
f(real_args.get());
// Choosing a function to be called later:
// Note that this captures a pointer to the data, not a copy of the data.
// Hence changes to the data will be reflected when this is invoked.
func = [real_args]() { g(real_args.get()); };
// It's only here, as real_args is about to go out of scope, where
// we lose the type information.
args = real_args;
}
else {
// Similar to the above, so I'll reduce the commentary.
auto real_args = std::make_shared<args_st<float,float>>();
func = [real_args]() { g(real_args.get()); };
args = real_args;
}
/* other code that does stuff with args */
/* This code is probably poor C++ style, but that can be addressed later. */
// Invoke the function.
func();
return 0;
}
Your next step probably should be to do some reading on these features so you understand what this code does. Then you should be in a better position to leverage the power of C++.

Avoid a call to a function that may throw in a destructor

I have a ODBC wrapper interface that enables me to execute SQL queries in C++. In particular, I use
the named parameter idiom for
the select statements, for example:
Table.Select("foo").GroupBy("bar").OrderBy("baz");
To achieve this effect, the class Table_t returns a proxy object Select_t:
class Table_t
{
// ...
public:
Select_t Select(std::string const &Stmt)
{ return {*this, Stmt}; }
void Execute(std::string const &Stmt);
};
Select_t combines the basic statement with the additional clauses and executes the actual statement in the destructor:
class Select_t
{
private:
Table_t &Table;
std::string SelectStmt,
OrderStmt,
GroupStmt;
public:
Select_t(Table_t &Table_, std::string const &SelectStmt) :
Table(Table_), SelectStmt(SelectStmt_) {}
~Select_t()
{ /* Combine the statements */ Table.Execute(/* Combined statement */); }
Select_t &OrderBy(std::string const &OrderStmt_)
{ OrderStmt = OrderStmt_; return *this; }
Select_t &GroupBy(std::string const &GroupStmt_)
{ GroupStmt = GroupStmt_; return *this; }
};
The problem is that Table.Execute(Stmt) may throw and I must not throw in a destructor. Is there a
way I can work around that while retaining the named parameter idiom?
So far the only idea I came up with is to add an Execute function to Select_t, but I would prefer not to:
Table.Select("foo").GroupBy("bar").OrderBy("baz").Execute();
Throwing "inside" a destructor is not a problem; the problem is exceptions escaping from a destructor. You need to catch the ODBC exception, and decide how to communicate the error by another interface.
Actually, separating the concerns of the query object and its execution might be a good idea.
Lazy invocation can be very useful.
The Execute function could reasonably be a free function.
For example:
auto myquery = Table.Select("foo").GroupBy("bar").OrderBy("baz");
auto future_result = marshal_to_background_thread(myquery);
//or
auto result = Execute(myquery);
This would lend itself to re-use with respect to prepared statements.
e.g.
auto myquery = Prepare(Table.Select("foo").Where(Equals("name", Param(1))).OrderBy("baz"));
auto result = Execute(myquery, {1, "bob"});
result = Execute(myquery, {1, "alice"});

Pass a callback function with a parameter to a function

I want to call the following function and pass it a function with a parameter. The purpose of that is that it should call the function with my specified parameter so I know what triggered the function (in that case a gpio pin on the Raspberry Pi).
int wiringPiISR( int pin, int edgeType, void (*function)( void ) );
Currently I have:
for ( int i = 0; i < myValues.size(); ++i )
{
int myValue = myValues[ i ];
wiringPiISR( myValue, INT_EDGE_RISING, &myCallback( myValue ) );
}
Though this is giving me the following error:
error: lvalue required as unary ‘&’ operand
Which I can't really understand as to my understanding, myValue is an lvalue or is it not?
Is it what I want do even possible? If so how?
The function wiringPiISR is from a library called wiringPi and I would like to avoid modifying it as much as possible.
You could combine the answers from imreal and Ryan Haining something like this.
std::function<void()> cbfunc;
void myCallback()
{
cbfunc();
}
void myWiringPiISR(int val, int mask, std::function<void()> callback)
{
cbfunc = callback;
wiringPiISR(val, mask, &myCallback);
}
... and then use it...
void myActualCallback(int v)
{
... do something...
}
myWiringPiISR(myValue, INT_EDGE_RISING, std::bind(myActualCallback, myValue));
No need to patch library, and you can use all the bind/function goodness. I'll leave you to find a way around the thread safety issues...
How does it work? Put simply 'std::bind' is binding together a function and it's parameters into a single std:function object which can then be 'called' from the myCallback function which acts as a shim around the callback that you pass. I'd given the callback function a confusing name before, but this edit has hopefully fixed that.
You can "vomit" the function. This doesn't require a user-defined mutable global variable and is thread-safe, unless you have a compiler that supports multiple threads but not per-thread exceptions which would be basically unusable.
myWiringPiISRWrapper(Value value, int edge, std::function<void()> func) {
try {
throw &func;
} catch(...) {
myWiringPiISR(value, edge, [] {
try {
throw;
} catch(std::function<void()>* func) {
(*func)();
}
});
}
}
It's disgusting and slow, but it's totally encapsulated which I think is a worthwhile upside. Note that this only works if the callback is never executed after the call to myWiringPiISR returns. In this case you can of course have a callback with whatever bound state you desire.
If myValue is something you can decide at compile time, you could set it statically and use an intermediate function to pass in.
void myCallbackHelper() {
static constexpr int myValue = 3;
myCallback(myValue);
}
wiringPiISR(myValue, INT_EDGE_RISING, &myCallbackHelper);
If you need to determine myValue at run time, you could still accomplish this, but not really thread-safely.
int& getMyValue() {
static int myValue;
return myValue;
}
void setMyValue(int i) {
getMyValue() = i;
}
void myCallbackHelper() {
myCallback(getMyValue());
}
Then set it and call
setMyValue(3);
wiringPiISR(myValue, INT_EDGE_RISING, &myCallbackHelper);
I looked up wiringPiISR and found that it is some sort of api call, so i am assuming you cannot change it.
Having said that, there is a reason most api-calls with a function-pointer-callback look sort of like this
void setCallback( void (*function)(void* data), void* userdata);
This allows people to cast their struct {blabla} data; to add some userdata, and when the function is called, it is passed along.
So basically, apart from hacking stuff with static variables, you can't pass any arguments.
You need to use std::function and std::bind.
Change your function signature to
int wiringPiISR (int pin, int edgeType, std::function<void()> func);
Inside you can call the callback simply using func()
And your call to:
int myValue = 3;
wiringPiISR(myValue, INT_EDGE_RISING, std::bind(myCallback, myValue));
What this does is create a std::function object (i.e. a callable) that wraps your function and keeps your desired value in its state.
This will only work on C++11 and newer.
If you have c++11, I suggest using std::function - it's quite a bit cleaner.
If not, your function signature is wrong. You want a callback with the type void(int) but your function takes a void()

Calling GSL function inside a class in a shared library

I'm trying make a shared library in c++ implementing tools for Fermi gases. I'm using the GSL library to solve a function numerically and my code runs without a problem without when running as a script, but when trying to convert it to a shared library and classes I encounter problems.
I've seen similar questions:
Q1
Q2
Q3
I'm fairly new to c++-programming and cannot seem to adapt the different answers to my problem. Probably since I do not quite understand the answers.
My code is:
/* Define structure for the GSL-function: chempot_integrand */
struct chempot_integrand_params { double mu; double T; };
double
ChemicalPotential::chempot_integrand (double x, void * params){
/* Computes the integrand for the integral used to obtain the chemical potential.
*
* This is a GSL-function, which are integrated using gsl_integration_qag.
*/
// Get input parameters.
struct chempot_integrand_params * p = (struct chempot_integrand_params *) params;
double mu = p->mu;
double T = p->T;
// Initiate output parameters for GSL-function.
gsl_sf_result_e10 result;
int status = gsl_sf_exp_e10_e( ( gsl_pow_2(x) - mu ) / T , &result );
if (status != GSL_SUCCESS){
printf ("Fault in calculating exponential function.");
}
// Return (double) integrand.
return (gsl_pow_2(x) / ( 1 + result.val * gsl_sf_pow_int(10,result.e10) ));
}
/* Define structure for the GSL-function: chempot_integration */
struct chempot_integral_params { double T; };
double
ChemicalPotential::chempot_integration (double mu, double T){
/* Computes the integral used to obtain the chemical potential using the integrand: chempot_integrand.
*/
// Set input parameters for the integrand: chempot_integrand.
struct chempot_integrand_params params_integrand = { mu, T };
// Initiate the numerical integration.
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000); // Allocate memory for the numerical integration. Can be made larger if neccessary, REMEMBER to change it in the function call: gsl_integration_qag as well.
double result, error;
gsl_function F;
F.function = &ChemicalPotential::chempot_integrand;
F.params = &params_integrand;
// Upper limit for integration
double TOL = 1e-9;
double upp_lim = - T * gsl_sf_log(TOL) + 10;
gsl_integration_qag (&F, 0, upp_lim, 1e-12, 1e-12, 1000, 6, w, &result, &error);
// Free memory used for the integration.
gsl_integration_workspace_free (w);
return result;
}
and when compiling I get the error
error: cannot convert ‘double (Fermi_Gas::ChemicalPotential::*)(double, void*)’ to ‘double (*)(double, void*)’
in line
F.function = &ChemicalPotential::chempot_integrand;
It is indeed interesting that people ask this over and over again. One reason may be that the proposed solutions are not easy to understand. I for one had problems understanding and implementing them. (the solutions did not work out of the box for me, as you might expect.)
With the help of tlamadon I just figured out a solution that may be helpful here as well. Let's see what you guys think.
So just to recap, the problem is that you have a class that contains a member function on which you want to operate with something from the GSL library. Our example is useful if the GSL interface requires a
gsl_function F;
see here for a definition.
So here is the example class:
class MyClass {
private:
gsl_f_pars *p; // not necessary to have as member
public:
double obj(double x, void * pars); // objective fun
double GetSolution( void );
void setPars( gsl_f_pars * xp ) { p = xp; };
double getC( void ) ; // helper fun
};
The objective of this exercise is to be able to
initiate MyClass test,
supply it with a paramter struct (or write a corresponding constructor), and
call test.GetSolution() on it, which should return whatever the GSL function was used for (the minimum of obj, a root, the integral or whatever)
The trick is now to put have an element in the parameter struct gsl_f_pars which is a pointer to MyClass. Here's the struct:
struct gsl_f_pars {
double a;
double b;
double c;
MyClass * pt_MyClass;
};
The final piece is to provide a wrapper that will be called inside MyClass::GetSolution() (the wrapper is a stand in for the member function MyClass::obj, which we cannot just point to with &obj inside the class). This wrapper will take the parameter struct, dereference pt_MyClass and evaluate pt_MyClass's member obj:
// Wrapper that points to member function
// Trick: MyClass is an element of the gsl_f_pars struct
// so we can tease the value of the objective function out
// of there.
double gslClassWrapper(double x, void * pp) {
gsl_f_pars *p = (gsl_f_pars *)pp;
return p->pt_MyClass->obj(x,p);
}
The full example is a bit too long to post here, so I put up a gist. It's a header file and a cpp file, it should be working wherever you have GSL. Compile and run with
g++ MyClass.cpp -lgsl -o test
./test
This is a duplicate question. See Q1 or Q2 for example. Your problem is the following: you cannot convert pointers to member functions to free function pointers. To solve your problem, there are two options. You can define your member function as static (which is bad in 90% of the case because the member function will not be attached to any instantiation of your class and that is why you can convert it to a free function) or you can use the wrapper you linked that will use a static member functions under the hood to make your code compatible with gsl without the need of declaring your particular member function static.
EDIT #Florian Oswald. Basically your entire solution can be implemented in 2 lines using std::bind the wrapper I cited before
gsl_function_pp Fp( std::bind(&Class::member_function, &(*this), std::placeholders::_1) );
gsl_function *F = static_cast<gsl_function*>(&Fp);
In practice is this is just 1 extra line from a pure C code!
As I stated in a comment, wrapping every member function that you want to integrate using an extra global struct and an extra global function is cumbersome and pollute your code with a lot of extra functions/struct that are completely unnecessary. Why use c++ if we refuse to use the features that make C++ powerful and useful (in comparison to C)?
Another classical Example: if you want to pass a LOT of parameters, use lambda functions (no extra struct or global functions) !!!
To be more precise: Imagine you have 2 parameters (doubles) .
//Declare them (locally) here
double a1 = ...;
double a2 = ...;
// Declare a lambda function that capture all of them by value or reference
// no need to write another struct with these 2 parameters + class pointer
auto ptr = [&](double x)->double {/.../};
// Cast to GSL in 3 lines using the wrapper
std::function<double(double)> F1(ptr);
gsl_function_pp F2(F1);
gsl_function *F = static_cast<gsl_function*>(&F2);
No extra global struct of global functions and no extra wrapper (the same wrapper that solved the problem of integrating member function also solved the problem of integrating a lambda expression). Of course this is a matter of style in the end, but in the absence of these nice features that allow the use of C libraries without code bloat, I would never leave C.

Operating on a string before runtime

I have a string:
B<T>::B() [with T = int]
Is there any way I can get
B<T> [with T = int] from this before run time somehow? :)
Simplifying: Is there any way to get X & Y separately from a static string XY defined as a preprocessor macro in any form before runtime?
In current C++ I cannot think on a way to split the string at compile time. Most of the template tricks will not work on string literals. Now, I imagine that you want this to use in some sort of logging mechanism and you want to avoid the impact of performing the split at runtime in each method invocation. If that is the case, consider adding a function that will perform the operation and then in each function a static const std::string to hold the value. That string will be initialized only once in the first call to the function:
#define DEFINE_LOG_NAME static const std::string _function_name( parse( __PRETTY_FUNCTION__ ) )
#define LOG_NAME( level ) do { DEFINE_LOG_NAME; log( level, _function_name ); } while (0)
std::string parse( std::string const & pretty ) {
// split here, return value
}
template <typename T>
struct B {
B() {
LOG_NAME( DEBUG );
}
};
(I have not tested this, so you might need to fiddle with it)
This will have some runtime impact, but only once for each function. Also note that this approach is not thread safe: if two threads simultaneously call a method that has not been called before there will be a race condition.
is this what you wanted ?
#define X "X"
#define Y "Y"
#define XY string(X) + Y
static string s = XY;