Я хочу написать такой код, но не могу:
#define COLOR "red"
#define RED "red"
#define BLUE "blue"
int main()
{
// following code can't be compiled
#if (COLOR==RED)
cout<<"red"<<endl;
#endif
// following code can work
if (COLOR==RED)
cout<<"red"<<endl;
else
cout<<"notred"<<endl;
}
Итак, как я могу реализовать сравнение строк в выражении #if? или может это не возможно?
Кстати, я знаю, что могу реализовать другими способами, например:
#define COLOR 1
#define RED 1
#define BLUE 2
// can be compiled and word correctly
#if (COLOR==RED)
cout<<"red"<<endl;
#endif
Даже if (COLOR==RED)
не обязательно должно быть правдой. «Являются ли все строковые литералы разными (то есть хранятся в непересекающихся объектах) и дают ли последовательные оценки строкового литерала тот же или другой объект не указано».
@EtiennedeMartel: 1 надеюсь, что выражения имеют значение, насколько это возможно, для меня число 1 2 3 не имеет никакого значения. другими словами, я хочу лучшего опыта чтения. 2 в некоторых случаях я хочу, чтобы макрос, например COLOR, вводил мое имя файла с содержимым «красный», например.
добавить проблему: как я могу напечатать макрос в виде строки в имя файла? как мы знаем, макрос будет заменен пропроцессором. Есть ли какие-то хитрости?
Чтобы расширить то, что сказал @RaymondChen: "red" == "red"
не обязательно должно быть правдой; два литерала можно хранить отдельно, или их можно рассматривать как один литерал.
Да, конечно, но зачем использовать препроцессор, а не константы? Вы пишете C++, а не C, у вас есть настоящие константы.
Потому что #if работает только с целыми числами
expression is a C expression of integer type, subject to stringent restrictions. It may contain...
см. https://gcc.gnu.org/onlinedocs/gcc-3.0.1/cpp_4.html#SEC38
#include <iostream>
// internal functions, can be put into included header
#define TRUE 1
#define XEQUAL(a, b) a##_##b
#define EQUAL(a, b) XEQUAL(a, b)
#define XCUSTOMSTR(a) color_##a
#define CUSTOMSTR(a) XCUSTOMSTR(a)
#define XSTR(a) #a
#define STR(a) XSTR(a)
// define available colors
#define red_red TRUE
#define blue_blue TRUE
#define green_green TRUE
// optional custom names
#define color_green "grün"
#define COLOR red
#define COLOR2 green
int main() {
#if EQUAL(COLOR, red)
std::cout << "my_"STR(COLOR)"_file.txt";
#endif
#if EQUAL(COLOR, COLOR2)
char filename[] = "my_"STR(COLOR2)"_file.txt";
std::cout << filename;
#endif
std::cout << CUSTOMSTR(green);
return 0;
}
Хитрость заключается в том, чтобы сравнить до, сделав из него строку.
Препроцессор не может обрабатывать строки (кроме их генерации), но может обрабатывать текстовые токены!
не может работать, ошибка: токен не является допустимым бинарным оператором в подвыражении препроцессора
Сравнение @Aerterliusi теперь работает, и вы можете использовать текст макроса в именах файлов.
Есть ли причина, по которой вы хотите использовать препроцессор для этого?