Могу ли я объединить пространство имен с именем класса, используя ##
директива препроцессора?
Я написал этот пример, чтобы показать, что я хочу сделать:
namespace ns {
class A
{
public:
void print(){ std::cout << "A" << std::endl; };
};
}
#define PRINT_NS(E) ([](){ ::ns::##E e; e.print(); }())
int main()
{
PRINT_NS(A);
}
Это дает следующую ошибку компиляции:
13:30: error: pasting "::" and "A" does not give a valid preprocessing token
17:3: note: in expansion of macro 'PRINT_NS'
Похоже, что до ::
не считается ##
,
В этом случае не нужно ничего клеить, так как ::
не препроцессор, токен препроцессор сможет заменить Е просто отлично (рабочий пример):
#define PRINT_NS(E) ([](){ ::ns::E e; e.print(); }())
##
следует использовать, когда вы хотите склеить части, которые в противном случае будут рассматриваться как один токен, что-то вроде этого:
#define PRINT_NS(E) ([](){ ::ns::My_##E e; e.print(); }())
Других решений пока нет …