如何在C++中为 if 和 else 语句定义新行为



我正在做的项目涉及一个类,让它成为myClass,它类似于一个集合,我需要允许程序员以有意义的方式比较这种类型的对象。

我希望能够做的是这样的:

myClass a, b;
...
if (a == b)
{
//execute code where a and b are implicitly used as
// each of a and b's elements, respectively
}

并让我的自定义 if 语句根据对元素对执行的条件,为 A 和 B 中的每对元素执行条件代码。

下面是一个更具体的例子:

myClass a = {1, 2}, b = {2, 3};
if (a == b)
std::cout << a << " equals " << b << std::endl;
else
std::cout << a << " does not equal " << b << std::endl;

结果在哪里(不一定按此顺序(:

1 does not equal 2
2 equals 2
1 does not equal 3
2 does not equal 3

目前,我重载了比较运算符以返回一个"比较类型",该类型仅存储两个操作数和用于延迟计算的比较函数。有没有办法完成此自定义 if/else 行为,以便在 if 语句收到类型为"比较类型"的参数时发生?或者是否有必要只定义一个接受这种类型的对象的常规函数和对二进制运算符函数的引用作为条件代码?

我看到了这个问题,但在这种情况下,简单地定义转换为布尔值是行不通的。 C++ "重载"if(( 语句

你可以接近:

myClass a = {1, 2}, b = {2, 3};
for(auto&& cmp:(a == b))
if(cmp)
std::cout << cmp.lhs << " equals " << cmp.rhs << std::endl;
else
std::cout << cmp.lhs << " does not equal " << cmp.rhs << std::endl;

只需在两个myClass上定义operator==即可返回可迭代对象。

每个可迭代元素都有一个lhs、一个rhs和一个转换为bool运算符。

template<class Lhs, class Rhs=Lhs, class Cmp=std::equal<>>
struct comparison_t {
Lhs lhs;
Rhs rhs;
operator bool()const{ return Cmp{}(lhs, rhs); }
};
struct myClass {
int a, b;
auto operator==( myClass const& lhs, myClass const& rhs ){
std::array<comparison_t<int const&>> retval={{
{lhs.a, rhs.a},
{lhs.b, rhs.a},
{lhs.a, rhs.b},
{lhs.b, rhs.b},
}};
return retval;
}
};

可能有一些错别字。

如果你能摆脱if/else的样式,你可以将ifelse块的主体作为 lambda 作为辅助函数。

template<class T, class F> void compare_all(const myClass &a, const myClass &b, T fn_true, F fn_false) {
for (const auto &ai: a.vec) {
for (const auto &bi: b.vec) {
if (ai == bi)
fn_true(ai, bi);
else
fn_false(ai, bi);
}
}
}

compare_all的前两个参数与operator==相同。 另外两个是 lambda,用于在元素比较相等或不相等时保存要执行的操作。 此处的示例假定myClass类中有一个名为vec的容器,用于保存要比较的项。

作为如何使用它的示例,下面介绍如何重写原始代码以使用此技术。

int main() {
myClass a{1, 2}, b{2, 3};
compare_all(a, b, 
[](int a, int b) { std::cout << a << " equals " << b << std::endl; },
[](int a, int b) { std::cout << a << " does not equal " << b << std::endl; }
);
}

最新更新