Как помочь компилятору вывести аргументы вариативной функции?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как помочь компилятору вывести аргументы вариативной функции?

Сообщение Anonymous »

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

Код: Выделить всё

#define ThisFile __FILE__  printIt;
};
Однако использование этого потребует изменения синтаксиса на что-то вроде Log::print, что нарушит большую часть устаревшего кода. Поэтому я решил обернуть это функцией:

Код: Выделить всё

#pragma once

#include 
#include 
#include 
#include 

struct Log
{
template
struct printIt
{
printIt(const char* format, Args&&...args, const std::source_location& loc)
{
const auto args_pack = std::tuple{ std::forward(args)...};
const auto msg = std::apply([&format](auto&...args) {
return std::vformat(format, std::make_format_args(args...));
}, args_pack);

std::println("{}:{} {}", loc.file_name(), loc.line(), msg);
}
};

template
printIt(const std::string_view, Args&&...) -> printIt;

template
static auto print(const std::string_view format, Args&...args,const std::source_location loc = std::source_location::current()) -> void
{
printIt(format, std::forward(args)..., loc);
}
};
Однако проблема в том, что мне нужно указать параметры шаблона, в котором я его вызываю:

Код: Выделить всё

#include "Log.hpp"

auto main() -> int
{
auto Logger = Log{};
const auto a = int{0};
const auto b = int{1};
Logger.print("{} {}", a, b);
}
Да, я понимаю, что в этом примере я удалил %d и заменил их на {}. Я написал код, который преобразует синтаксис стиля C и форматирует его в строку с помощью snprintf. Я также удалил ThisFile, поскольку он будет заменен на std::source_location. Я хочу добиться следующего:

Код: Выделить всё

#include "Log.hpp"

auto main() -> int
{
auto Logger = Log{};
const auto a = int{0};
const auto b = int{1};
Logger.print("%d %d", a, b);
}
Однако, если я это сделаю, я получу ошибку компилятора, которая говорит что-то вроде ошибки вывода/замены аргумента шаблона.
Нет ли способа добиться того, что я пытаюсь сделать, без указания типов, которые входят в параметр шаблона? Или я могу помочь компилятору, подсказав ему, к чему он должен прийти? Я знаю, что руководства по дедукции не могут работать с функциями, иначе я бы попытался сделать это первым, но я застрял здесь и не знаю, куда идти дальше.
Ссылка на Godbolt: https://godbolt.org/z/sG7MTzP1a

Подробнее здесь: https://stackoverflow.com/questions/798 ... c-function
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»