2016-10-06 13 views
2

Tstd::anyに入れると、any_cast<T>(my_any)で取得できます。しかし、現時点での投票段階での標準(= C++ 17)には、nulloptstd::any_cast<T>(oa.value())がある場合、nulloptを返すような関数が含まれていますか?そういう行に沿った何か?std :: anyとstd :: optionalのany_cast

編集:人々は実装を示唆しているように見えるので、私はまた、私は今のところ使用するものリストアップします:

/* using magic here to select between boost/std::experimental/std versions */ 

template<typename T> 
inline const optional<T> any_cast(const optional<any>& operand) 
{ 
    return operand ? 
     optional<T>(any_cast<T>(operand.value())) : 
     optional<T>(nullopt); 
} 

答えて

0

std::optionalbind(またはand_then)メンバ関数を持っていた場合(つまり、aはT -> optional<U>を取り、それを呼び出したりnulloptを返すのいずれかoptional<T>上の関数が)、それはあなたが探しているはずだものです:

std::optional<std::any>> oa; 

optional<T> opt_t = oa.bind([](std::any& v) -> std::optional<T> { 
    if (T* t = std::any_cast<T>(&v)) { 
     return *t; 
    } 
    else { 
     return std::nullopt; 
    } 
}); 

か、あなたが本当に直接any_cast<T>を呼び出し、投げに対処したい場合は、map:あなたは非メンバ関数として、それらを記述する必要があると思いますので、

optional<T> opt_t = oa.map([](std::any& v) { 
    return std::any_cast<T>(v); 
}); 

std::optionalは、しかし何の継続機能を持っていません。

1

std::optional proposalまたはstd::any proposalにそのようなものは記載されていません。

Iの戻り型は任意のオブジェクトの状態に応じて異なるので、連続関数を使用して実現するのは簡単であろうと仮定:

template <typename T, typename TOptional, typename TF> 
void any_cast_or_nullopt(TOptional&& o, TF&& f) 
{ 
    if(!o) return; 
    f(std::any_cast<T>(*o)); 
} 

適切な場合にSFINAEstatic_assert及び/又はを追加関数を制約します。値*oは、oの値のカテゴリに応じて転送する必要があります。使用例:

int out = -1; 

std::optional<std::any> x; 
x = 10; 

any_cast_or_nullopt<int>(x, [&out](int value) 
    { 
     out = value; 
    }); 

assert(out == 10); 
+0

私はあなたの提案が好きですが、本当に3つのテンプレート引数が必要ですか? – einpoklum

+0

正確性と柔軟性を望むなら、yes: 'any_cast'に' T'が使われます。 'TOptional'はオプションの値を完全に転送するために使われます。 'TF'は一般的な呼び出し可能なオブジェクトのために使われます。 'TOptional'を使わなくても実装できますが、' o'がr値として渡されたときに '* o'を正しく動かすためには、コードの繰り返しが必要です。 –

+0

しかし私はfを持っていません。あなたは、キャストとその結果の使用を組み合わせるように強制しています。キャストとは異なります。 – einpoklum

関連する問題