プログラムのABTを使用して、関数へのポインターを回避する(そしてそれらを安全でないと見なす)と、確かに可能と思われます。ClangのASTは(その名前にもかかわらず)そのようなABTです:関数の宣言と定義の両方が表示されます。一度に1つの定義で作業を行うことにより、すでに適切なベースラインが得られます。
一方で、これは実用的かと思います。問題は、メモリ割り当てを実行する関数が(自発的に)スローする可能性があるとマークされていることです(new
nullを返すことはなく、bad_alloc
代わりにスローするため)。したがって、noexcept
ほとんどの場合、機能は少数に制限されます。
そしてもちろん、@ GManNickGのようなすべての動的条件が公開されています。たとえば、次のようになります。
void foo(boost::optional<T> const t&) {
if (not t) { return; }
t->bar();
}
であっても、間接参照はスローされるT::bar
可能性があります(何もない場合)。もちろん、これは私たちがすでにこれを除外したという事実を無視しています(ここ)。noexcept
optional<T>
関数がいつ機能するかについて明確な条件throw
がないと、static
分析によって...役に立たないことが判明する可能性があります。言語イディオムは、例外を念頭に置いて設計されています。
注:余談として、オプションのクラスは、間接参照が公開されないように書き直すことができます。したがって、noexcept
(コールバックが存在する場合)次のようになります。
template <typename T>
class maybe {
public:
template <typename OnNone, typename OnJust>
void act(OnNone&& n, OnJust&& j) noexcept(noexcept(n()) and
noexcept(j(std::declval<T&>())))
{
if (not _assigned) { n(); return; }
j(*reinterpret_cast<T*>(&_storage));
}
private:
std::aligned_storage<sizeof(T), alignof(T)>::type _storage;
bool _assigned;
};
// No idea if this way of expressing the noexcept dependency is actually correct.