Использовать двойные двоеточия (::) в #define

Можно ли использовать двойные двоеточия в #define? Я хотел бы сохранить некоторые записи в файлах реализации, например. например:

// foo.h
#define template template <class T>
#define foo:: foo<T>::

template class foo {
  T& baz();
};

#include "foo.tpp"
#undef template
#undef foo::

// foo.tpp
template T& foo::baz() {
    // do stuff.
}

Но я получаю синтаксические ошибки, которые я действительно не понимаю. (См. Пример codepad):

Строка 11: ошибка: пропущенные пробелы после имени макроса
Строка 10: ошибка: дополнительные токены в конце директивы #undef
Строка 4: ошибка: "foo" не является шаблоном
компиляция завершена из-за -Wfatal-errors.

Ответы

Ответ 1

Нет. Имя макроса должно быть идентификатором; он не может состоять из других символов и не может состоять из нескольких токенов.

#define template является недопустимым, поскольку template не является идентификатором, это ключевое слово.

#define foo:: foo<T>:: был действителен в C90 и С++ 98: он определяет макрос с именем foo, который заменяется на :: foo<T>:: (это не то, что вы хотите сделать, но оно действительно). Однако это недопустимо в C99 и С++ 11, поскольку в новых версиях языков должно быть пробелы между именем объектно-ориентированного макроса и его списком замещения (маркеры, с которыми он заменен).