Есть ли способ присвоить # определенный термин? - PullRequest
3 голосов
/ 14 января 2011
#define BLAH word

cout << BLAH;

Есть ли способ сделать это?

Ответы [ 6 ]

5 голосов
/ 14 января 2011

Попробуйте

#define STRINGIFY(x) #x
#define STRINGIFYMACRO(y) STRINGIFY(y)

#define BLAH word
cout << STRINGIFYMACRO(BLAH);

Дополнительный уровень косвенности вызывает строковое значение макроса вместо имени макроса.

Проверено на ideone .

4 голосов
/ 14 января 2011
  1. 'cout' - это не то, что вы делаете. Это глобальная переменная, которая является экземпляром типа std::ostream. Вы могли бы сказать, например, «вывод на cout».

  2. #define выполняет текстовую подстановку. Это в основном так же, как если бы вы использовали поиск и замену в текстовом редакторе для замены BLAH на word. Таким образом, линия cout << BLAH; превращается в cout << word;. Если это не работает, это потому, что cout << word; не является допустимым утверждением в этой области. Препроцессор не заботится ни о каком окружающем тексте. У него практически нулевое понимание кода (он знает, как маркировать код, то есть разбивать операторы и другие знаки препинания, если вы не ставите пробелы, но это все).

1 голос
/ 14 января 2011

Я тестирую программу для разных представлений числа, т. Е. С плавающей и двойной.Я хочу, чтобы он распечатывал: «Тестирование на float», когда определенный термин является float.

Нет необходимости злоупотреблять макросами как примитивным typedef:

template<class T>
void do_test(char const *name) {
  std::cout << "Testing " << name << "...\n";
  T var = foo();
  bar(var);
}

int main() {
  do_test<float>("single precision");
  do_test<double>("double precision");
  return 0;
}

Обратите внимание, что это позволяетвы даете разные имена (надеюсь, более значимые) каждому тесту, а не просто приводите в соответствие параметры теста, но «float» и «double» могут быть именами, если хотите.

Если вы действительно, действительнохотел бы преобразовать параметры в строку или если вам просто интересно узнать о макросах:

#define DO_TEST(T) do_test<T>(#T)
int main() {
  DO_TEST(float);
  DO_TEST(double);
  return 0;
}
1 голос
/ 14 января 2011

Я подозреваю, что вы хотите что-то вроде этого:

#include <typeinfo>

template <typename T>
void print_type()
{
    std::cout << typeid(T).name() << std::endl;
}

int main()
{
    print_type<float>();
    print_type<int>();
}

Обратите внимание, что значение typeid(T).name() определяется реализацией и может вообще не иметь значения.Невозможно гарантированно распечатать тип без написания функции для каждого типа самостоятельно.

Вы можете сделать перегрузку, которая также выводит тип выражения:

#include <typeinfo>

template <typename T>
void print_type(const T&)
{
    std::cout << typeid(T).name() << std::endl;
}

int main()
{
    print_type(5.0f);
    print_type(5.0);
}

(Обратите внимание, что это оценивает выражение, которое не нужно, но я сомневаюсь, что это вызывает беспокойство.)

1 голос
/ 14 января 2011

Если вы хотите напечатать слово "word", вы можете сделать:

#define STRINGIFY(x) #x

cout << STRINGIFY(word);
0 голосов
/ 14 января 2011

ОК, давайте попробуем это снова, основываясь на вашем комментарии:

Я тестирую программу для разных представлений числа, т. Е. С плавающей и двойной. Я хочу, чтобы он распечатал: «Тестирование на плавающее», когда заданный термин является плавающим.

Похоже, это то, что вы действительно имеете в виду:

У меня есть код, подобный следующему:

cout << "As a float:" << float(value) << endl;
cout << "As a double:" << double(value) << endl;

и я хочу сделать макрос для каждой из этих строк, чтобы текст соответствовал приведению типа.

В этом случае вам нужно что-то вроде этого:

#define DEBUG(t, x) cout << "As a " #t ":" << t(x) << endl

DEBUG(float, value);
DEBUG(double, value);
...