相当于C#的“?”的C ++。空条件运算符

时间:2019-11-01 16:51:57

标签: c++ operators

在C#中,有一个空条件运算符?.

MyObject o = null;

o?.doSomeThing();

意思是:

if(o != null)
    o.doSomeThing();

我想在C ++中有类似的东西:

MyObject* o = nullptr;

o?>doSomeThing(); // or o?->

如果有人这样写,这将非常有用:

o?.getO()?.getO()?.doSomeThing();

所以我有两个问题:

  1. 今天,我们将宏用于一行条件执行。 C ++ 14中有没有不使用宏的简便方法?
  2. 在任何地方都有讨论或建议吗?我什么都没找到。

2 个答案:

答案 0 :(得分:1)

不,没有语法可以做到这一点,也没有办法创建所述语法。

同样,没有提议(据我所知)添加它。

相反,您可以自己编写出null检查,或者更好的方法是通过重组代码以减少可以变为“ null”的位置数来使它们不再需要

答案 1 :(得分:-1)

WRT问题1:

constexprinline函数是宏函数的类型安全的C ++等效项。不保证它们可以内联您的代码,但是它们授予编译器按需进行复制的权限,而积极的编译器将为您进行内联。许多标准库类都做出了这种假设(例如std::vector<T>::size())。

编辑:好的,你们见得见,但公平。这是解决问题的一种方法:

编辑:已更新,可以根据要求在C ++ 14中进行编译。我知道这已被标记为重复,并且没人会看它,但是其他链接仅是C ++ 17。它还终止于非指针成员,并返回指向它们的指针,这与C#更加一致,后者将值类型转换为Nullable。

#include <cstdio>
#include <type_traits>

template <typename Class>
struct SafePtrImpl { 
    Class* ptr;

    SafePtrImpl(Class* ptr) : ptr(ptr) { }

    template <typename TClass, typename TResult, std::enable_if_t<std::is_pointer<TResult>::value, std::nullptr_t> = nullptr>
    inline SafePtrImpl<
        std::remove_pointer_t<
            std::remove_reference_t<
                TResult>>> operator ->*(TResult TClass::*member) {
        return SafePtr(ptr ? ptr->*member : nullptr);
    }

    template <typename TClass, typename TResult, std::enable_if_t<!std::is_pointer<TResult>::value, std::nullptr_t> = nullptr>
    inline TResult* operator ->*(TResult TClass::*member) {
        return ptr ? &(ptr->*member) : nullptr;
    }
};

template <typename TClass>
SafePtrImpl<TClass> SafePtr(TClass* ptr) { return SafePtrImpl<TClass>(ptr); }

// --

struct Foo {
    int x;
};

struct Bar {
    Foo* y;
};

int main() {
    Foo a { 42 };
    Bar b { &a };
    Bar c { nullptr };
    Bar* d = nullptr;

    int* b_y_x = SafePtr(&b)->*&Bar::y->*&Foo::x;
    int* c_y_x = SafePtr(&c)->*&Bar::y->*&Foo::x;
    int* d_y_x = SafePtr(d)->*&Bar::y->*&Foo::x;
    printf("b: %08x %d\n", b_y_x, *b_y_x);
    printf("c: %08x\n", c_y_x);
    printf("d: %08x\n", d_y_x);

    return 0;
}

https://godbolt.org/z/RYZ1EV

输出:

b: 3aa42aec 42
c: 00000000
d: 00000000