独自の「オプションのペア」を作成するのにそれほど時間はかかりません (に似てboost::optional<std::pair<…>>
いますが、インターフェイスが異なります)。たとえば、次のようになります。
template <typename T1, typename T2> struct OptPair : std::pair<T1, T2>
{
typedef std::pair<T1, T2> base_t;
bool contains;
OptPair() : contains(true) {}
explicit OptPair(bool x) : contains(x) {}
OptPair(const T1& x, const T2& y) : base_t(x, y), contains(true) {}
template <class U, class V>
OptPair(const std::pair<U,V> &p) : base_t(p), contains(true) {}
template <class U, class V> OptPair(const OptPair<U,V> &p) : base_t(p), contains(p.contains) {}
// No need to define operator=, as the default will construct an OptPair<T1, T2>
// if necessary, then copy members into *this.
};
template <typename T1, typename T2>
OptPair<T1, T2> makeOptPair() { return OptPair<T1, T2>(); }
template <typename T1, typename T2>
OptPair<T1, T2> makeOptPair(const T1 &x, const T2 &y) {
OptPair<T1, T2> p(true);
p.first = x;
p.second = y;
return p;
}
template <typename OS, typename T1, typename T2>
OS &operator<<(OS &os, const OptPair<T1, T2>& p) {
os << "<OptPair: ";
if (p.contains) os << p.first << ", " << p.second;
else os << "empty";
os << ">";
return os;
}
次に、std::pair と同じように使用できます (また、値を前後に代入して std::pair と交換可能に使用することもできます) が、次のように「空の」値を戻す機能が追加されています。
OptPair<int, int> someFunction()
{
...
return OptPair<int, int>(false);
}
次のように、使用する前に必ず結果を確認する必要があります。
void doStuffWithPair(std::pair<int, int>);
void doStuffWithEmpty();
...
OptPair<int, int> ret = someFunction();
if (ret.contains) doStuffWithPair(ret);
else doStuffWithEmpty();