有没有人试图在C中实现类似Haskell的case语句?

我想知道是否有人知道这个的实现(或尝试实现).

在哈斯克尔

Haskell有一个表达式,通过模式匹配执行区分:

let a = [1,2,3] in
let is_empty = case a of
      [] -> True
      (_:_) -> False in
-- Note: is_empty == False
...

在C.

C重载分辨率与模式匹配类似.可以始终定义一个重载集来对类型进行大小写区分,但在许多情况下,使用表达式会更方便.

我可以看到这在C 14中几乎可以起作用:

template<typename Head, typename Tail>
using Cons = boost::tuples::cons<Head, Tail>;
using Nil = boost::tuples::null_type;

template<typename Tuple>
bool is_empty(Tuple const & tuple)
{
  return case_of(tuple)(
      [](Cons<auto,auto> const &) { return false; }
    , [](Nil) { return true; }
    );
}

但我不认为Cons< auto,auto> (或任何类似的东西)在任何版本的C中都有效.我们有通用的lambdas,但在这种情况下我想在lambda中进行模板参数推导.

那么,野外有没有像这样的案例呢?或者有人知道一次尝试失败吗?

或者你能看到如何实现我想要的模式匹配吗?它必须完全包含在表达式中.

最佳答案 去年俄罗斯Habrahabr网站上有一篇关于某种模式匹配的文章.它允许您匹配类型(是的,更像是类型匹配)甚至是一些布尔编译时条件.它看起来像这样:

template<class T>
decltype(auto) test(T& value) {
    return match(value
        ,[](std::string value)    { cout << "This is string"; return value + " Hi!"; }
        ,[](int i)                { cout << "This is int";    return i * 100; }
        ,[](auto a)               { cout << "This is default";return nullptr; }
    );
}

match(true_type{}
         ,[](bool_constant< T::value == 10 >)                        { cout << "1" ; }
         ,[](bool_constant< (T::value == 20 && sizeof...(Args)>4) >) { cout << "2" ; }
    );

你可以在blog post itself找到更多的代码片段和实现细节.这个博客文章的灵感来自于这个CMach7库,在某些地方博客文章作者的意见相当丑陋,但允许你写这样的东西:

// Fibonacci numbers
int fib(int n)
{
    var<int> m;

    Match(n)
    {
      Case(1)     return 1;
      Case(2)     return 1;
      Case(2*m)   return sqr(fib(m+1)) - sqr(fib(m-1));
      Case(2*m+1) return sqr(fib(m+1)) + sqr(fib(m));
    }
    EndMatch
}

但不知道列表.您可以查找其他答案和/或实现自定义列表匹配器.

点赞