Нет, как уже сказал Джеймс, в препроцессоре нет способа разделить токены или узнать длину строки.
Но я думаю, что для вашего случая использования это вообще не нужно. Строка, которую вы получили бы при строковом аргументе #x
, представляет собой строку постоянного размера, например, chicken
приводит к "chicken"
, который просто имеет тип char[8]
. Длина такой строки является постоянной времени компиляции, и вы просто можете определить ее с помощью sizeof
:
#define TOKLEN(TOK) (sizeof(#TOK)-1)
Использование такой вещи в C "просто" выглядит
#define SCARY(TOK) for (size_t i = 0; i < TOKLEN(TOK); ++i) printf("%c:", #TOK[i])
Поскольку TOKLEN(TOK)
является константой времени компиляции, компилятор может развернуть ее, если необходимо.
Чтобы использовать это в вашем случае для C ++
template < size_t n >
class constLenString {
size_t const len = n;
char const* str;
constLenString(char* s) : str(s) { }
};
#define defConstLenString(TOK, NAME) constLenString< TOKLEN(TOK) > NAME(#TOK)
(не проверено, мой C ++ ржавый)
и теперь с
defConstLenString(chicken, chick);
chick.n
- это константа, которая может быть границей цикла for
или чего-либо еще, и компилятор должен иметь возможность оптимизировать все идеально.