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