gpt4 book ai didi

c++ - 是否可以在 C++ 中实现 DefaultIfNull 函数?

转载 作者:行者123 更新时间:2023-12-03 18:28:28 28 4
gpt4 key购买 nike

免责声明:这更多是出于好奇,而不是缺乏其他解决方案!
是否可以在 C++ 中实现一个函数 :

  • 传递了一个 T 类型的指针
  • 要么向 T
  • 指向的对象返回一个类似引用的东西
  • 或者,如果指针为空,则返回一个类似引用的东西到默认构造的 T()有一些理智的生活?

  • 我们的第一次尝试是:
    template<typename T>
    T& DefaultIfNullDangling(T* ptr) {
    if (!ptr) {
    return T(); // xxx warning C4172: returning address of local variable or temporary
    } else {
    return *ptr;
    }
    }
    第二次尝试是这样完成的:
    template<typename T>
    T& DefaultIfNull(T* ptr, T&& callSiteTemp = T()) {
    if (!ptr) {
    return callSiteTemp;
    } else {
    return *ptr;
    }
    }
    这消除了警告和 somewhat extends the lifetime临时的,但我认为它仍然很容易出错。

    背景:
    整个过程是由如下所示的访问模式触发的:
    if (pThing) {
    for (auto& subThing : pThing->subs1) {
    // ...
    if (subThing.pSubSub) {
    for (auto& subSubThing : *(subThing.pSubSub)) {
    // ...
    }
    }
    }
    }
    可以“简化”为:
    for (auto& subThing : DefaultIfNull(pThing).subs1) {
    // ...
    for (auto& subSubThing : DefaultIfNull(subThing.pSubSub)) {
    // ...
    }
    }

    最佳答案

    是的,但它会很丑:

    #include <stdio.h>

    #include <variant>

    template <class T>
    struct Proxy {
    private:
    std::variant<T*, T> m_data = nullptr;

    public:
    Proxy(T* p) {
    if (p)
    m_data = p;
    else
    m_data = T{};
    }

    T* operator->() {
    struct Visitor {
    T* operator()(T* t) { return t; }
    T* operator()(T& t) { return &t; }
    };

    return std::visit(Visitor{}, m_data);
    }
    };

    struct Thing1 {
    int pSubSub[3] = {};
    auto begin() const { return pSubSub; }
    auto end() const { return pSubSub + 3; }
    };

    struct Thing2 {
    Thing1* subs1[3] = {};
    auto begin() const { return subs1; }
    auto end() const { return subs1 + 3; }
    };

    template <class T>
    auto NullOrDefault(T* p) {
    return Proxy<T>(p);
    }

    int main() {
    Thing1 a{1, 2, 3}, b{4, 5, 6};
    Thing2 c{&a, nullptr, &b};

    auto pThing = &c;

    for (auto& subThing : NullOrDefault(pThing)->subs1) {
    for (auto& subSubThing : NullOrDefault(subThing)->pSubSub) {
    printf("%d, ", subSubThing);
    }
    putchar('\n');
    }
    }

    关于c++ - 是否可以在 C++ 中实现 DefaultIfNull 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67587339/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com