c++:引用包装器和printf

C++: reference wrappers and printf

本文关键字:printf 包装 引用 c++      更新时间:2023-10-16

我有一个std::reference_wrapper对象的std::vector,我想用printf(没有cout)打印;现在,如果我写

int a=5;
std::reference_wrapper<int> b=a;
printf("%inn",b);

我得到一个无意义的数字(我认为是a的地址);要获取我的值,我必须执行

printf("%inn",b.get());

是否有一种方法可以自动调用printf中的.get()函数(例如,打印我reference_wrapper content的不同%规格),以便我可以制作一个与std::reference_wrapper<type>type一起工作的广义函数?

您可能希望至少考虑使用c++ IO库而不是遗留的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;                                                    
}