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;                                                    
}
Другие вопросы по тегам