필자는이 방법을 최소한으로 검증 할 수있는 방법을 찾기 위해 애를 썼지 만 어떻게해야하는지 생각할 수 없습니다. 나는 함께 추가하려고하는 두 가지 예상 유형이 있습니다. 예상되는 데이터 유형은 int, double 등일 수 있습니다. 예외 일 수 있습니다. 이론적으로 예외를 가진 데이터 유형을 추가 할 수 있어야하며 값을 물어 보면 프로그램을 정상적으로 실행할 수 있습니다. 프로그램을 중단하지 않고 예외를 반환해야합니다.템플릿 형식으로 C++ 연산자를 오버로드하면 오류가 발생합니다.
나는이 프로그램을 실행하려고 할 때마다 어디서부터 시작해야할지 모를 수백 줄의 오류 메시지를 볼 수 있는데, 하나의 오류는 no matching function for call to 'operator+(double&,double&)
인지 알지 못한다. 2 개의 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;
}
'그건 : 당신이 원하는 무엇을, 거의 항상, 그 결과를 결정하기 위해 metafunction를 사용하여 다음 임의의 호출을 추론하고있다. 'variant :: which'를 호출하여 저장된 값의 타입의 인덱스를 얻을 수 있습니다. –
유효한 @MaximEgorushkin? 'isValid()'또는 부울'valid? 이() == '0'state.which 같이 계산 될 수 있기 때문에 – Sailanarmo
'valid' 데이터 부재는 불필요하다. –