在C#中,有一个空条件运算符?.
:
MyObject o = null;
o?.doSomeThing();
意思是:
if(o != null)
o.doSomeThing();
我想在C ++中有类似的东西:
MyObject* o = nullptr;
o?>doSomeThing(); // or o?->
如果有人这样写,这将非常有用:
o?.getO()?.getO()?.doSomeThing();
所以我有两个问题:
答案 0 :(得分:1)
不,没有语法可以做到这一点,也没有办法创建所述语法。
同样,没有提议(据我所知)添加它。
相反,您可以自己编写出null检查,或者更好的方法是通过重组代码以减少可以变为“ null”的位置数来使它们不再需要
答案 1 :(得分:-1)
WRT问题1:
constexpr
和inline
函数是宏函数的类型安全的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;
}
输出:
b: 3aa42aec 42
c: 00000000
d: 00000000