Is it possible to expand a macro into two piece of data with different types

Viewed 46

UPDATE

It seems that the original question is not that clear, so I made another example to specify what I need.

#define RPC_FUNC(X) &X,???   // I don't know how...

class Test {
public:
    static void func(int a) {}
};


int main()
{
    const auto ptr1 = std::make_pair(&Test::func, "Test::func");
    // const auto ptr2 = std::make_pair(RPC_FUNC(Test::func));
    // ptr2.first(123);  // this should call the function Test::func
    // std::cout << ptr2.second; // this should print the string "Test::func"
    
    return 0;
}

How to define the macro RPC_FUNC to make this code work? Meaning that I want to make ptr1 and ptr2 exactly the same.

ORIGINAL

I want to do a piece of code like this:

template<typename F> // F is the type of some functions
void func(F f, const std::string& funcMark) {
    // do something
}

I want to pass a non-static member function and a string into the function func.

Sometimes, the second parameter is just the name of the first one. Let's see an example:

namespace sp {
class Test {
public:
    void doJob() {}
};
}

func(&sp::Test::doJob, "doJob");

What I'm trying to do is to do the call above like this: func(MY_MARCO(sp::Test::doJob)).

Meaning that, the macro MY_MACRO should do expand its parameter sp::Test::doJob into &sp::Test::doJob, "doJob".

1 Answers

The specification what the macro should precisely do is dim. The stringizing operator # can turn macro argument into string literal:

// example code what it does
#include <iostream>

#define YOUR_MACRO(X) X() << " from " << #X "()"

int foo() { return 42; }

int main() { std::cout << YOUR_MACRO(foo) << std::endl; }

That outputs

42 from foo()

Turning string literal into std::string is also trivial:

#include <iostream>
#include <string>

#define YOUR_MACRO(X) X() << " from " << std::string(#X "()")

int foo() { return 42; }

int main() { std::cout << YOUR_MACRO(foo) << std::endl; } 

Works same. So where are you stuck?

UPDATE:

Specification is now lot better! But ... it is basically same what I already posted that you should use stringizing operator # in macro:

#include <iostream>

#define RPC_FUNC(X) &X, #X

class Test {
public:
    static void func(int a) {
        std::cout << "called Test::func(" << a << ")" << std::endl;
    }
};

int main() {
    const auto ptr1 = std::make_pair(&Test::func, "Test::func"); // gets warning about unused variable
    const auto ptr2 = std::make_pair(RPC_FUNC(Test::func));
    ptr2.first(123);  // prints "called Test::func(123)"
    std::cout << ptr2.second << std::endl; // prints "Test::func"
    return 0;
}
Related