检查统一数据的最佳方法是什么?

时间:2019-09-18 12:11:33

标签: c++ c++11 software-design

在以下情况下,我需要一个主意(请参阅代码以清楚了解):具有结构MyData的多个实例,检查实例是否统一并返回统一实例的最简洁方法是什么。如何在保持可读性的同时减少代码重复? 均匀性是指具有相同的值。

给出以下示例:

struct MyData {
   int foo;
   int bar;
   // ...
}

void print(MyData d)
{
    std::cout << "MyData[" << d.foo << ", " << d.bar << "]" std::endl;
}

MyData data1 = {5, 6};
MyData data2 = {5, 6};
MyData data3 = {5, 42};

我正在寻找一种良好的代码样式来获得所需的输出:

isUniform(data1, data2);
 >>> MyData[5, 6]

isUniform(data1, data2, data3);
 >>> "Not uniform"

1 个答案:

答案 0 :(得分:1)

首先,为MyData定义一个相等运算符,以便我们可以比较实例:

bool operator == (MyData const &lhs, MyData const &rhs) {
    return std::tie(lhs.foo, lhs.bar)
        == std::tie(rhs.foo, rhs.bar);
}

注意:使用operator <=>在C ++ 20中将很快变得更容易。

然后,只需解压缩isUniform的所有参数,然后查看它们是否相等即可。这里是C ++ 11解决方案,下面是C ++ 17。

template <class First, class... Rest>
bool isUniform(First const &first, Rest const &... rest) {
    bool all_equal = true;

    bool expander[]{ false, (all_equal = all_equal && first == rest)... };
    static_cast<void>(expander);

    return all_equal;
}

用法如下:

if(isUniform(data1, data2))
    print(data1);
else
    std::cout << "Not uniform\n";

See it live on Wandbox


C ++ 17版本:

template <class First, class... Rest>
std::optional<First> isUniform(First const &first, Rest const &... rest) {
    if(((first == rest) && ...))
        return first;

    return {};
}

用法如下:

if(auto o = isUniform(data1, data2, data3))
    print(*o);
else
    std::cout << "Not uniform\n";

See it live on Wandbox