나는 boost::variant
을 사용할 수 있으며이 질문을하지 않아도된다는 것을 알고 있습니다. 그러나 boost::variant
을 사용하면 많은 추악한 코드가 포함됩니다. 특히 방문객은 지저분합니다. 그래서, 더 이상 고민하지 않고 ...매개 변수없는 펑터와 C++에서 반환 값의 차별화 된 통합을 구현하는 방법은 무엇입니까?
나는 카레 기능의 게으른 평가를 구현하기 위해 다음과 같은 템플릿 클래스를 작성했습니다. (전체 조각에 대한 my previous question를 참조하십시오.)
template <typename> class curry;
template <typename _Res>
class curry< _Res() >
{
public:
typedef std::function< _Res() > _Fun;
typedef _Res _Ret;
private:
_Fun _fun;
public:
explicit curry (_Fun fun)
: _fun(fun) { }
operator _Ret()
{ return _fun(); }
};
그래서 내가 메모이 제이션을 포함하도록 업데이트 할. 개념적으로 매우 간단합니다.
private:
_Fun _fun;
public:
explicit curry (_Fun fun)
: _fun(fun) { }
으로 :
private:
bool _evaluated; // Already evaluated?
union
{
_Fun _fun; // No
_Res _res; // Yes
};
public:
explicit curry (_Fun fun)
: _evaluated(false), _fun(fun) { }
explicit curry (_Res res)
: _evaluated(true), _res(res) { }
을하지만 왼쪽 두 가지가 있습니다 첫째, 나는 대체해야합니다. 첫째, 나는 operator _Ret
을 업데이트해야합니다. 그렇게하면 게으른 평가를 수행하면 결과가 실제로 memoized됩니다. 둘째, _evaluated
값에 따라 _fun
또는 _res
중 하나가 삭제되도록 소멸자를 추가해야합니다. 그리고 여기에 어떻게 해야할지 잘 모르겠습니다.
먼저 _fun
을 _res
으로 바꾸는 올바른 방법입니까? 그렇지 않다면 어떻게해야합니까?
operator _Ret()
{
if (!_evaluated) {
_Fun fun = _fun;
// Critical two lines.
_fun.~_Fun();
_res._Res(fun());
_evaluated = true;
}
return _res;
}
둘째, 이것은 선택적 _fun
_res
또는 파괴하는 올바른 방법? 그렇지 않다면 어떻게해야합니까?
~curry()
{
if (_evaluated)
_res.~_Res();
else
_fun.~_Fun();
}
Yikes. 어딘가에는 추함이있을 것입니다. 날씨는 Visitor 패턴이나 다른 곳에 있습니다. –
@ JohnDibling : C++에 적절한 자동 태그화된 유니온 타입이있는 경우 ... 그러나 패턴 매칭을 사용하면 완전히 유용하고 깨끗하게 사용할 수 있습니다. – pyon
나는 당신이 여기서하려고하는 것을 완전히 이해하지 못하고있다. 무엇이든 포함 할 수 있지만 Visitor 패턴을 사용하지 않는 변형 유형을 다시 구현하려고합니까? –