-5

Is there a way to define variadic template macro just like variadic macro?

For example, if define variadic macro like:

#define PRINT_STRING(fmtId, ...) { \
    CString fmt; \
    fmt.FormatString(fmt, ##__VA_ARGS__); \
    cout << fmt << endl; }

Could we define something like:

#define PARSE_FUNCTION(functionName, typename...) \
    std::function<int(typename...)> m_##functionName(){ \
        return (std::function<int(typename...)>) functionName; }
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Mark Guo
  • 213
  • 4
  • 11
  • What? can you explain what you want in more detail, i didn't get it... – Thibaut Apr 23 '13 at 01:13
  • 5
    Macros and templates aren't the same thing. This looks like an XY problem. Explain what it is that you're trying to *achieve*, rather than how you're trying to do it. – Nicol Bolas Apr 23 '13 at 01:22
  • Thanks, yes, I think it is a stupid question too :) – Mark Guo Apr 23 '13 at 03:11
  • @Nicol: I can't understand your comment! Why should someone not write a macro which holds an template? It is not the question that macros are the bad side of c/c++, but there are still reasons to use them. Indeed: I could also not understand the code sample :-) – Klaus Apr 23 '13 at 08:14
  • @Klaus: It's not whether someone can put a template inside a macro. It's that there's no such thing as a "macro template". They do different stuff. – Nicol Bolas Apr 23 '13 at 09:14

1 Answers1

1

__VA_ARGS__ can be used multiple times, so you could write:

#define PARSE_FUNCTION(functionName, ...) \
    std::function<int(__VA_ARGS__)> m_##functionName() { \
        return std::function<int(__VA_ARGS__)>(functionName); \
    }

What is happening is just simple text substitution, whether the arguments is for a template or not won't be checked by the preprocessor.

Actually any function objects can be implicitly converted to a std::function, so the cast can be omitted. Furthermore, if functionName refers to function pointers, the exact type can be easily inferred, that you don't need the variadic macro at all:

#define PARSE_FUNCTION(functionName) \
    auto m_##functionName() \
        -> std::function<std::remove_pointer<decltype(functionName)>::type> \
    { \
        return functionName; \
    }
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005