C++:参考包装器和 printf
C++: reference wrappers and 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());
有没有办法在 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{};
printf
不进行隐式类型转换,至少在这种情况下不会为您的 std::reference_wrapper 调用转换运算符,要使其工作,您需要使用可以进行类型转换的东西, 比如 std::cout
.
#include <iostream>
int a=5;
std::reference_wrapper<int> b=a;
int main() {
std::cout<<b<<std::endl;
}
我有 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());
有没有办法在 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{};
printf
不进行隐式类型转换,至少在这种情况下不会为您的 std::reference_wrapper 调用转换运算符,要使其工作,您需要使用可以进行类型转换的东西, 比如 std::cout
.
#include <iostream>
int a=5;
std::reference_wrapper<int> b=a;
int main() {
std::cout<<b<<std::endl;
}