C++: справочные оболочки и printf
У меня есть std::vector
из std::reference_wrapper
объекты, которые я хочу напечатать с помощью printf (без cout); сейчас, если я напишу
int a=5;
std::reference_wrapper<int> b=a;
printf("%i\n\n",b);
Я получаю чепуху (я думаю, это адрес a
); чтобы получить свою ценность, я должен сделать
printf("%i\n\n",b.get());
Есть ли способ сделать автоматический звонок на .get()
функция в printf
(например, другой %
Спецификатор, который печатает мне reference_wrapper content
) поэтому я могу сделать обобщенную функцию, которая работает как с std::reference_wrapper<type>
а также type
?
3 ответа
Возможно, вы захотите хотя бы рассмотреть возможность использования библиотеки ввода-вывода C++ вместо устаревших функций C. При этом, вы можете написать обертку вокруг printf
обеспечить развертывание эталонных упаковщиков:
template<typename... Params>
void my_printf(char const* fmt, Params&&... ps)
{
printf(fmt, unwrap(std::forward<Params>(ps))...);
}
с unwrap
реализовано следующим образом:
template<typename T>
decltype(auto) unwrap_impl(T&& t, std::false_type){
return std::forward<T>(t);
}
template<typename T>
decltype(auto) unwrap_impl(T&& t, std::true_type){
return t.get();
}
template<typename T>
decltype(auto) unwrap(T&& t)
{
return unwrap_impl(std::forward<T>(t), is_reference_wrapper<std::decay_t<T>>{});
}
и is_reference_wrapper
черта характера:
template<typename T>
struct is_reference_wrapper : std::false_type {};
template<typename T>
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type{};
printf()
является функцией библиотеки C, которая абсолютно ничего не знает о классах и ссылках C++ и никогда ничего о них не узнает.
C++ имеет собственную библиотеку ввода / вывода, которая использует потоковые объекты, которая знает о классах C++ и о том, как их использовать:
#include <iostream>
#include <memory>
int main()
{
int a=5;
std::reference_wrapper<int> b=a;
std::cout << b << std::endl;
return 0;
}
Выход:
5
printf
не выполняет неявное преобразование типов, по крайней мере, не вызывает оператор преобразования в этом случае для вашего std::reference_wrapper, чтобы заставить его работать, вам нужно использовать что-то, что может выполнять преобразование типов, например std::cout
,
#include <iostream>
int a=5;
std::reference_wrapper<int> b=a;
int main() {
std::cout<<b<<std::endl;
}