我想知道是否有人知道这个的实现(或尝试实现)。
在Haskell
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中进行模板参数推导。
那么,野外有没有像这样的情况呢?或者有人知道尝试失败了吗?
或者你能看到如何实现我想要的模式匹配吗?它必须完全包含在表达式中。
答案 0 :(得分:2)
去年俄罗斯 Habrahabr 网站上有一篇关于C ++中某种模式匹配的文章。它允许您匹配类型(是的,更像是类型匹配)甚至是一些布尔编译时条件。它看起来像这样:
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中找到更多代码段和实施细节。这个博客文章的灵感来自于这个C ++ Mach7库,在某些地方,博客文章作者的意见相当丑陋,但允许你写这样的东西:
// 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
}
但不知道列表。您可以查找其他答案和/或实现自定义列表匹配器。