在 MSVC chrono 实现中我看到以下代码
_EXPORT_STD template <int = 0>
_NODISCARD constexpr year_month operator+(const year_month& _Left, const months& _Right) noexcept {
const auto _Mo = static_cast<long long>(static_cast<unsigned int>(_Left.month())) + (_Right.count() - 1);
const auto _Div = (_Mo >= 0 ? _Mo : _Mo - 11) / 12;
return year_month{_Left.year() + years{_Div}, month{static_cast<unsigned int>(_Mo - _Div * 12 + 1)}};
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下为什么它使用带有未命名参数的模板吗?
BoP*_*BoP 29
您有两个非常相似的重载operator+,最初没有模板
template <int = 0>
constexpr year_month operator+(const year_month& _Left, const months& _Right) noexcept
constexpr year_month operator+(const year_month& _Left, const years& _Right) noexcept
Run Code Online (Sandbox Code Playgroud)
人们发现,如果您有一个可同时转换为months和 的值years,则此处存在歧义。应该选择哪种转换?
通过制作其中一个运算符(虚拟)模板,可以选择非模板(如果可能),因为模板在重载决策中具有较低的优先级。
该标准规定了这个要求有点复杂(我认为是倒退的):
“如果调用者为月份参数提供的参数可转换为年份,则其到年份的隐式转换序列比其到月份的隐式转换序列更差”
因此,如果转换同样好,则应选择非模板。只有当转换为月份更好时,模板才有机会。
(并且该标准没有明确表示必须是模板,但这是实现此要求的一种方式)。
| 归档时间: |
|
| 查看次数: |
1440 次 |
| 最近记录: |