roz*_*zzy 17 c++ cpp-core-guidelines
在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
Run Code Online (Sandbox Code Playgroud)
我对这个例子的最后两行特别感兴趣.第一个似乎暗示如果你没有提供带有参数的单位change_speed就会抛出一个错误.最后一行显示使用一些m和s文字定义的单位.现代版C++中是否都有这些新功能?如果是这样,将如何实现这样的东西,以及需要什么版本的C++?
lub*_*bgr 15
正如评论中所提到的,核心指南中的示例使用用户定义的文字来构建直观地表示物理量的特定于应用程序的类型.为了说明具体示例,请考虑以下类型:
/* "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;
};
Run Code Online (Sandbox Code Playgroud)
跟踪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};
}
Run Code Online (Sandbox Code Playgroud)
他们让你实例化这样的Length对象:
/* We use auto here, because the suffix is so crystal clear: */
const auto lengthInMeter = 23_m;
const auto lengthInKilometer = 23_km;
Run Code Online (Sandbox Code Playgroud)
为了构造一个Speed实例,让我们定义一个合适的运算符来除以Lengtha 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()};
}
Run Code Online (Sandbox Code Playgroud)
现在,让我们再看一下核心指南中的示例,
void change_speed(const Speed& s)
{
/* Complicated stuff... */
}
Run Code Online (Sandbox Code Playgroud)
但最重要的是,你如何调用这样一个函数:
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;
}
Run Code Online (Sandbox Code Playgroud)
正如@KillzoneKid在评论中提到的那样,C++ 11是必需的.