在 C++ Core Guidlines P.1 change_speed
示例,它显示了一个 Speed
类型,使用如下所示:
change_speed(Speed s); // better: the meaning of s is specified
// ...
change_speed(2.3); // error: no unit
change_speed(23m / 10s); // meters per second
我对这个例子的最后两行特别感兴趣。第一个似乎表明,如果您没有为 change_speed
提供参数的单位,它将引发错误。最后一行显示了使用一些 m
和 s
文字定义的单位。现代版本的 C++ 中是否有这两个新特性?如果是这样,如何实现这样的东西,需要什么版本的 C++?
最佳答案
正如评论中提到的,核心指南中的示例使用用户定义的文字来构造直观表示物理量的特定于应用程序的类型。为了在具体示例中说明它们,请考虑以下类型:
/* "Strong" speed type, unit is always [m/s]. */
struct Speed {
long double value;
};
/* "Strong" length type, parameterized by a unit as multiples of [m]. */
template <class Period = std::ratio<1>> struct Length {
unsigned long long value;
};
跟踪 Length
对象的单位可能没有多大意义,但对于 Speed
实例则不然,但让我们在这里考虑最简单的示例。现在,让我们看看两个用户定义的文字:
#include <ratio>
auto operator ""_m(unsigned long long n)
{
return Length<>{n};
}
auto operator ""_km(unsigned long long n)
{
return Length<std::kilo>{n};
}
它们让您像这样实例化 Length
对象:
/* We use auto here, because the suffix is so crystal clear: */
const auto lengthInMeter = 23_m;
const auto lengthInKilometer = 23_km;
为了构造一个 Speed
实例,让我们定义一个合适的运算符来将 Length
除以 duration
:
#include <chrono>
template <class LengthRatio, class Rep, class DurationRatio>
auto operator / (const Length<LengthRatio>& lhs,
const std::chrono::duration<Rep, DurationRatio>& rhs)
{
const auto lengthFactor = static_cast<double>(LengthRatio::num)/LengthRatio::den;
const auto rhsInSeconds = std::chrono::duration_cast<std::chrono::seconds>(rhs);
return Speed{lengthFactor*lhs.value/rhsInSeconds.count()};
}
现在,让我们再次看一下核心指南中的示例,
void change_speed(const Speed& s)
{
/* Complicated stuff... */
}
但最重要的是,如何调用这样的函数:
using namespace std::chrono_literals;
int main(int, char **)
{
change_speed(23_m/1s);
change_speed(42_km/3600s);
change_speed(42_km/1h);
return 0;
}
正如评论中提到的@KillzoneKid,需要 C++11 才能工作。
关于c++ - C++ 中类型的单位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51943434/