C++可以像ML案例表达式那样做吗?

Nat*_*nax 3 c++ pattern-matching switch-statement

所以,我在C++中遇到过几次这样的事情,我真的很喜欢写这样的东西

case (a,b,c,d) of
     (true, true, _, _ )     => expr
   | (false, true, _, false) => expr
   | ...
Run Code Online (Sandbox Code Playgroud)

但是在C++中,我总是得到这样的东西:

bool c11 = color1.count(e.first)>0;
bool c21 = color2.count(e.first)>0;
bool c12 = color1.count(e.second)>0;
bool c22 = color2.count(e.second)>0;
// no vertex in this edge is colored
// requeue
if( !(c11||c21||c12||c22) )
{
    edges.push(e);
}
// endpoints already same color
// failure condition
else if( (c11&&c12)||(c21&&c22) )
{
    results.push_back("NOT BICOLORABLE.");
    return true;
}
// nothing to do: nodes are already
// colored and different from one another
else if( (c11&&c22)||(c21&&c12) )
{
}
// first is c1, second is not set
else if( c11 && !(c12||c22) )
{
    color2.insert( e.second );
}
// first is c2, second is not set
else if( c21 && !(c12||c22) )
{
    color1.insert( e.second );
}
// first is not set, second is c1
else if( !(c11||c21) && c12 )
{
    color2.insert( e.first );
}
// first is not set, second is c2
else if( !(c11||c21) && c22 )
{
    color1.insert( e.first );
}
else
{
    std::cout << "Something went wrong.\n";
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有任何方法可以清除所有这些,如果是,而且其他方式,因为它似乎特别容易出错.如果一个案例表达式(或C++中的语句)并非详尽无遗,那么可能会让编译器像SML一样抱怨它会更好.我意识到这个问题有点模糊.也许,总而言之,如何用简洁的C++中的任意数量的变量代表一个详尽的真值表?提前致谢.

Bow*_*ens 7

我喜欢艾伦的解决方案,但我恭敬地不同意他的结论,即它过于复杂.如果您可以访问C++ 11,它几乎可以为您提供所需的所有工具.您只需要编写一个类和两个函数:

namespace always {

struct always_eq_t {
};

template <class lhs_t>
bool operator==(lhs_t const&, always_eq_t)
{
    return true;
}

template <class rhs_t>
bool operator==(always_eq_t, rhs_t const&)
{
    return true;
}

}  // always
Run Code Online (Sandbox Code Playgroud)

然后你可以用与ML相似的方式编写你的函数:

#include <tuple>
#include <iostream>

void f(bool a, bool b, bool c, bool d)
{
    always::always_eq_t _;

    auto abcd = std::make_tuple(a, b, c, d);

    if (abcd        == std::make_tuple(true,  true, _, _)) {
        std::cout << "true, true, _, _\n";
    } else if (abcd == std::make_tuple(false, true, _, false)) {
        std::cout << "false, true, _, false\n";
    } else {
        std::cout << "else\n";
    }
}

int
main()
{
    f(true, true, true, true);
    f(false, true, true, false);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在C++中,您经常要考虑是否有一种合理的类型可以帮助我更轻松地编写代码?另外,我认为如果你有ML背景,你将从检查C++模板中受益匪浅.它们在C++中应用函数式编程风格非常有用.


Ala*_*jeu 5

C++传统上面向个人,无论语法如何,您都无法做任何类似于以下内容的事情.

if ([a,b,c,d] == [true,true,false, false]) {}
Run Code Online (Sandbox Code Playgroud)

New C++标准有一些东西可以让你定义内联常量数组,因此可以定义一个类,它将数组作为构造函数并支持这样的比较.就像是

auto x = multi_val({a,b,c,d});
if (x == multi_val({true, true, false, false}))
{ ... }
else if (x == multi_val(etc.))
Run Code Online (Sandbox Code Playgroud)

但是现在要像_一样进行部分匹配,这不是直接支持的,你必须让你的类更加复杂以捏造它,比如使用一个可能的模板类型并且去

multi_val(true, true, maybe<bool>(), maybe<bool>)
Run Code Online (Sandbox Code Playgroud)

这进入了相当令人兴奋的C++领域,绝对不是我会做的那么基本的东西.