Тип поведения RAII времени компиляции с использованием C ++ - PullRequest
4 голосов
/ 30 мая 2011

Я знаю, это звучит немного странно, но это то, что я хочу сделать: допустим, у меня есть функция void f(), и я хочу добавить трассировку для этого метода.Я хочу отследить вход этой функции и выход из нее с помощью сообщений трассировки, таких как «Введенная функция f» и «Выход из функции f».Я не хочу добавлять записи трассировки вручную для входа и выхода, поскольку я могу пропустить некоторые пути возврата.Таким образом, можно использовать шаблонную магию во время компиляции и автоматически генерировать эти строки.то есть то, чего я хочу достичь, это

void f()
{
  some_template<magic>("f");
}

. Это должно добавить трассировочное сообщение "Введенная функция f" в конструкторе и "Выход из функции f" в деструкторе.Я хочу, чтобы он компилировался, и не хочу создавать объекты во время выполнения.Возможно ли это в C ++?какие-нибудь указатели, где я могу найти больше информации, если это может быть достигнуто?

Ответы [ 4 ]

4 голосов
/ 30 мая 2011

Точка, в которой оставлен метод, известна только во время выполнения, поскольку любое исключение может произойти в любой точке вашего кода (вообще говоря).Следовательно, решение во время компиляции здесь невозможно.

4 голосов
/ 30 мая 2011

Вам действительно нужно попросить отладчик или компилятор выполнить эту работу. Вы не можете использовать RAII без создания объекта, и, кроме того, ни один шаблон не может иметь доступа к имени вашей функции.

Однако, если вы можете принять объект, то это не страшно.

class tracer {
    std::string exit;
public:
    tracer(std::string entry, std::string exit_)
        : exit(exit_) {
        std::cout << entry;
    }
    ~tracer() { std::cout << exit; }
};

void f() {
    tracer scope("Oh hai, I is entering f()", "Oh bai, I is leaving f()");
}
0 голосов
/ 30 мая 2011

Если вы действительно серьезно относитесь к этому, использование AspectC ++ является одним из вариантов. Тем не менее, порог для этого достаточно высок, и я думаю, что вы окажетесь залитыми выводом, если вы сделаете что-то подобное. Лучшим вариантом было бы использовать отладчик (установка точек останова, который печатает некоторый вывод) или хороший старый printf / cout, заключенный в класс, как предлагает DeadMG. ___FILE___ и ___LINE___ могут быть полезны для такого класса.

0 голосов
/ 30 мая 2011

В любом случае весь код создается во время компиляции, так в чем же проблема с классом? Компилятор прикрепит вызовы конструктора и деструктора там, где они принадлежат, и это именно то, что вы хотите. Стоимость выполнения вызывает эти функции, что совершенно неизбежно, так как это ваша цель.

Может показаться, что сохранение "f" обойдется вам в char const*, но любой приличный оптимизатор заметит, что строковый литерал является константой, которая не изменяется во всей функции, поэтому его не нужно хранить но можно перезагрузить. Пусть оптимизатор решит, эффективно ли кэшировать указатель; Я не могу предсказать это.

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