Макрос отладки для C ++ с переменными аргументами без строки формата - PullRequest
3 голосов
/ 25 декабря 2011

Можно ли написать макрос, который может принимать переменное число аргументов и расширяется следующим образом:

quickdebug(a)   ->  cout << #a ": " << a;
quickdebug(a,b) ->  cout << #a ": " << a << #b ": "<< b;

и т.д.

Если нет, могу ли я хотя бы вывести все аргументы без указания форматных строк? * например 1006 *

quickdebug2(a)   -> cout << a ;
quickdebug2(a,b) -> cout << a << " " << b ;

и т.д.

Например, в Java, я могу написать функцию, которая предоставляет мне аналогичные функции:

void debug(Object...args) 
{
  System.out.println(Arrays.deepToString(args));
}

Ответы [ 2 ]

6 голосов
/ 25 декабря 2011

Используя переопределяющий класс, оператор:

class VariadicToOutputStream
{
public:
    VariadicToOutputStream(std::ostream& s, const std::string& separator = " ") : m_stream(s), m_hasEntries(false), m_separator(separator) {}
    template<typename ObjectType>
    VariadicToOutputStream& operator , (const ObjectType& v)
    {
        if (m_hasEntries) m_stream << m_separator;
        m_stream << v;
        m_hasEntries=true;
        return *this;
    }
    ~VariadicToOutputStream()
    {
        m_stream << std::endl;
    }

private:
    std::ostream& m_stream;
    bool m_hasEntries;
    std::string m_separator;
};

Вы можете написать, например:

VariadicToOutputStream(std::cout) , 1, 0.5f, "a string";

Затем можно обернуть макросом препроцессора:

#define VARIADIC_TO_STDOUT(...)     VariadicToOutputStream(std::cout),__VA_ARGS__;

Итак, вы можете написать:

VARIADIC_TO_STDOUT(1, 0.5f, "a string");

Было бы легко добавить f.i. разделительные строки для использования между аргументами.

Редактировать: я просто добавил пробел по умолчанию в качестве разделительной строки.

1 голос
/ 25 декабря 2011

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

#define quickdebug(...) functiontocall("test", __VA_ARGS__)

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

Итак: quickdebug(1, 2, "123", 4.5) становится functioncall("test", 1, 2 , "123", 4.5)

Однако в какой-то момент вам нужно использовать эти аргументы, и здесь это может стать чрезвычайно трудным, если у вас нет строки формата или что-то еще, указывающее тип аргументов.

Проблема в том, что при чтении переменных из списка переменных аргументов вам необходимо знать тип аргумента или хотя бы его размер. На вашем месте я бы выбрал другой подход.

Подробнее о вариационных макросах можно прочитать здесь: http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...