防止使用不同单位的变量进行算术运算

时间:2018-09-10 19:30:38

标签: c++

我们有带有英制和公制单位的c ++例程。由于外部数据格式,将所有内容转换为单个测量系统是不切实际的。混合方程式中的单位而不进行转换会导致很难发现的错误。我可以使用typedef来创建英制或公制数据类型,但这不会阻止混合使用。我可以在变量名后添加后缀“ I”或“ M”,以使单位更明显,但这也不能防止混合使用。谁能建议一种方法指定变量使用的单位,以便编译器(或静态分析工具)可以标记混合使用?

2 个答案:

答案 0 :(得分:4)

对于初学者来说,对于此类强类型,您可以为每个单元定义不同的类型,然后通过使用不同等式的模板化版本来实施混合规则。与此类似的可扩展线:

template <typename T>
struct Imperial
{
    T value;
};

template <typename T>
struct Metric
{
    T value;
};

template <typename U>
void SomeEquation(U lhs, U rhs)
{
    // Equation logic
}

int main()
{
    Imperial<double> feet{3.28084};
    Metric<double> meters{1.0};

    SomeEquation(feet, feet);      // OK
    SomeEquation(meters, meters);  // OK
    //SomeEquation(feet, meters);    // Compilation error

    return 0;
}

如果需要,可以专门针对特定单位类型的方程式代码:

template <typename T>
void SomeEquation(Metric<T> lhs, Metric<T> rhs)
{
    // Specialized equation logic for metric types
}

感谢user defined literals -那些在评论中提到的内容让我发现了:o -(自C ++ 11起)您可以修改代码以添加此类定义:

Imperial<long double> operator"" _foot(long double value)
{
    return Imperial<long double>{value};
}

Metric<long double> operator"" _meter(long double value)
{
    return Metric<long double>{value};
} 

然后通过以下便捷方式进行使用:

int main()
{
    auto feet = 3.28084_foot;
    auto meters = 1.0_meter;

    SomeEquation(feet, feet);      // OK
    SomeEquation(meters, meters);  // OK
    //SomeEquation(feet, meters);    // Compilation error

    return 0;
}

您可以使用它live here

答案 1 :(得分:0)

您想要的是“强类型”,即围绕英制和公制不同类型的原始类型(String content = steps.readFile("doc_html.tar.gz") InputStream inp = null inp = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)) byte[] buffer = new byte[4096]; int bytesRead = -1; while ((bytesRead = inp.read(buffer)) != -1) { outputStream.write(buffer); } outputStream.flush(); inp.close(); int甚至是double)的模板包装。使用不同的类型会使编译器抱怨非法分配和操作。

在所有背景下都可以实现强类型的一种方法:https://www.fluentcpp.com/2016/12/08/strong-types-for-strong-interfaces/

您可以进一步推广该思想,并实现运算符以方便进行算术运算。