C++:参考包装器和 printf

C++: reference wrappers and printf

我有 std::vectorstd::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());

有没有办法在 printf 中自动调用 .get() 函数(例如,一个不同的 % 说明符打印 reference_wrapper content)这样我就可以适用于 std::reference_wrapper<type>type?

的广义函数

printf() 是一个 C 库函数,它对 C++ 类 和引用一无所知,并且永远不会知道它们。

C++ 有自己的 input/output 库,它使用流对象,了解 C++ 类 以及如何使用它们:

#include <iostream>

#include <memory>

int main()
{
    int a=5;
    std::reference_wrapper<int> b=a;

    std::cout << b << std::endl;

    return 0;
}

输出:

5

您可能至少要考虑使用 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{};

demo

printf 不进行隐式类型转换,至少在这种情况下不会为您的 std::reference_wrapper 调用转换运算符,要使其工作,您需要使用可以进行类型转换的东西, 比如 std::cout.

#include <iostream>                                                             

int a=5;                                                                        
std::reference_wrapper<int> b=a;                                                

int main() {                                                                                                                           
    std::cout<<b<<std::endl;                                                    
}