template<class T, class D>
class switch_with_default;
template<class T>
class switch_impl {
public:
    switch_impl(const T& t_) : t(&t_), matched(false) {}
    template<class U, class F>
    switch_impl& case_(const U& u, const F& f) {if(!matched&&*t==u){matched=true;f();}return *this;}
    template<class D>
    switch_with_default<T,D> default_(const D& d);
protected:
    template<class U, class D> 
    friend class switch_with_default;
    const T* t;
    bool matched;
};
template<class T, class D>
class switch_with_default {
public:
    template<class U, class F>
    switch_with_default& case_(const U& u, const F& f) {impl->case_(u,f); return *this;}
    ~switch_with_default() {if (!impl->matched) (*d)();}
protected:
    friend switch_impl<T>;
    switch_with_default(switch_impl<T>& impl_, const D& d_) :impl(&impl_), d(&d_) {}
    switch_impl<T>* impl;
    const D* d;
};
template<class T> template<class D>
switch_with_default<T,D> switch_impl<T>::default_(const D& d) {return switch_with_default<T,D>(*this, d);}
template<class T>
switch_impl<T> switch_(const T& t) {return switch_impl<T>(t);}





#include <iostream>
int main() {
    std::string input = "MooingDuck";
    
    switch_(input)
    .case_("First", [](){std::cout << "FAILURE1\n";})
    .case_("MooingDuck", [](){std::cout << "SUCCESS\n";})
    .case_("Third", [](){std::cout << "FAILURE2\n";});
    
    switch_(input)
    .case_("First", [](){std::cout << "FAILURE1\n";})
    .default_([](){std::cout << "SUCCESS\n";})
    .case_("Third", [](){std::cout << "FAILURE2\n";});
}


