私はこれを最小限の検証可能な例にする方法に苦労していますが、どうやってそれを行うのか考えることはできません。私は一緒に追加しようとしている2つの予想されるタイプがあります。予想されるデータ型は、int、doubleなどのデータ型にすることができます。例外でもかまいません。理論的には、例外を持つデータ型を追加することができなければなりません。値を求めても、プログラムを正常に実行することができます。プログラムをクラッシュさせずに例外を返す必要があります。テンプレート型のC++オペレータオーバーロードでエラーが発生する
このプログラムを実行しようとするたびに、何処から始めても何もわからないエラーメッセージが数百行あります。私が見ているエラーはno matching function for call to 'operator+(double&,double&)
です。これが正しいかどうかわかりません。 2つのExpectedを一緒に追加するには、型自体を追加したくありません。最後に、Expectedを追加して返され、Expectedを取得したいと思います。
私は本当にここにこだわっていますが、私はapply
の機能が正しく実装されていないと言われましたが、正にその理由がわかりません。私は間違って何をしていますか?
#include <stdexcept>
#include <exception>
#include <functional>
#include <variant>
template<typename T>
class Expected
{
public:
Expected(T t) : state(t), valid(true){}
Expected(std::exception_ptr e) : state(e), valid(false){}
Expected(std::exception e) : state(std::make_exception_ptr(e)), valid(false){}
T value() const
{
if(valid) return std::get<T>(state);
std::rethrow_exception(std::get<std::exception_ptr>(state));
}
bool isValid()
{
if(valid) return true;
return false;
}
template<typename U>
Expected<U> apply(std::function<U(T)> f)
{
if(!valid) return std::get<std::exception_ptr>(state);
try
{
return f(std::get<T>(state));
}
catch(...)
{
return std::current_exception();
}
}
private:
std::variant<T, std::exception_ptr> state;
bool valid;
};
template<typename T>
std::ostream& operator<< (std::ostream& o, Expected<T> e)
{
try
{
o << e.value();
}
catch(std::exception &a)
{
o << a.what();
}
catch(...)
{
o << "Unexpected Error";
}
return o;
}
template<typename T, typename V>
auto operator+(Expected<T> t, Expected<V> v)
{
return t.apply([&](T myT){return operator+(myT,v);});
}
template<typename T, typename V>
auto operator+(Expected<T> t, V v)
{
return t.apply([&](T myT){return operator+(myT,v);});
}
template<typename T, typename V>
auto operator+(V v, Expected<T> t)
{
return t.apply([&](T myT){return operator+(v,myT);});
}
int main()
{
Expected<int> a = 1;
Expected<int> b = 2;
std::cout << a + b << std::endl;
}
ここで 'valid'は厳密には必要ありません。 'variant :: which'を呼び出すと、格納されている値の型のインデックスを取得できます。 –
@ MaximEgorushkinは有効ですか? 'isValid()'またはブール値 'valid'を一緒に使う? – Sailanarmo
'valid.'データメンバーは' state.which()== 0'として計算できるので不要です。 –