I got a piece of code like this.
#define MAKE_SINGLETON_1(classname, traits) \ ; \ protected: \ friend class base::Singleton<classname, traits>; \ private: \ classname(const classname&) = delete; \ classname& operator=(const classname) = delete; \ protected: \ classname(); \ virtual ~classname(); #define MAKE_SINGLETON_2(classname) \ ; \ protected: \ friend class base::Singleton<classname>; \ private: \ classname(const classname&) = delete; \ classname& operator=(const classname) = delete; \ protected: \ classname(); \ virtual ~classname(); // selector #define MAKE_SINGLETON_X(x, A, B, FUNC, ...) FUNC // default parameter #define MAKE_SINGLETON(...) \ MAKE_SINGLETON_X(, ##__VA_ARGS__, MAKE_SINGLETON_1(__VA_ARGS__), MAKE_SINGLETON_2 (__VA_ARGS__)) } In other classes, it is used like this
class CConnManager: public Singleton<CConnManager, Mutex> { MAKE_SINGLETON( CConnManager, Mutex ) //other logic } I don't understand what MAKE_SINGLETON finally produces. Is it MAKE_SINGLETON_2 that finally called? Could anybody help me explain? Thank you very much.
MAKE_SINGLETON_1since that's the one with two arguments.FUNCis just the name of the argument there.MAKE_SINGLETON_Xexpands to whatever its fourth argument is. The fourth argument will either beMAKE_SINGLETON_1(__VA_ARGS__)orMAKE_SINGLETON_2 (__VA_ARGS__)depending on how many arguments__VA_ARGS__resolves to. So if you had two arguments, it would shift the rest of the arguments by one.