指针输出器

题目描述

给出用来输出指针的类 PointerPrinter 的定义。设 PointerPrinter 对象 obj,从 f 构造;ptr 是指向任意完整类型的指针,则 obj << ptr 可以输出 ptr 所指向的内容。如果 ptr 为空指针,则输出 f() 的值。

关于输入

无。

关于输出

见样例输出。

注意事项

  • Lambda 表达式是右值/临时值,因此在构造时不可以将它绑定到引用成员上,否则 Lambda 表达式析构后,成员便是悬垂引用。
  • 下述代码中的 const T* 可改为 TT&const T& 等,均不影响结果。

参考答案

#include <iostream>

template <typename F>
class PointerPrinter {
    F f;

public:
    PointerPrinter(F f) : f{f} {}

    template <typename T>
    PointerPrinter& operator<<(const T* t) {
        if (t) {
            std::cout << *t;
        } else {
            std::cout << f();
        }
        return *this;
    }
};

int main() {
    int nNull = 0;
    PointerPrinter sayNull([]() { return "null"; });
    PointerPrinter countNull([&]() { return ++nNull; });
    
    double doubles[]{0.0, -1.0, 3.14};
    for (auto i : doubles) {
        sayNull << &i << &" ";
    }
    std::cout << std::endl;

    int* ints[6]{new int{42}, nullptr, new int{0}, new int{-1}};
    for (auto ptr : ints) {
        countNull << ptr << " ";
    }
    sayNull << &"\nints have " << &nNull << &" null pointers.\n";

    for (auto ptr : ints) {
        if (!ptr) sayNull << &ptr << " " << ptr << "\n";
        delete ptr;
    }
}