::type-6ren">
gpt4 book ai didi

c++ - 参数列表中的模板方法 "=0"

转载 作者:搜寻专家 更新时间:2023-10-31 02:02:15 24 4
gpt4 key购买 nike

我看到了如下代码:

using EnableIfIntegral = typename std::enable_if<
std::is_integral<T>::value || std::is_enum<T>::value, int>::type;

template <typename T, EnableIfIntegral<T> = 0>
constexpr int Seconds(T n) {
return time_internal::FromInt64(n, std::ratio<1>{});
}

template <std::intmax_t N>
constexpr int FromInt64(int64_t v, std::ratio<1, N>) {
// Do Something
}

我明白什么是模板函数。为什么在模板参数列表中,有SomeClass<T> = 0? ?我知道T是模板参数。

为什么是std::ratio<1, N>一个参数?

最佳答案

我会回答你的两个问题中的第一个。

using EnableIfIntegral = typename std::enable_if<
std::is_integral<T>::value || std::is_enum<T>::value, int>::type;

我敢肯定你不小心遗漏了前一行应该是

template<typename T>

所以完整的声明是

template<typename T>
using EnableIfIntegral = typename std::enable_if<
std::is_integral<T>::value || std::is_enum<T>::value, int>::type;

这是一个难以下咽的大药丸,稍后我会回来讨论这个声明的更详细的细节,但这里发生的是,如果星星和月亮恰到好处地排列在一起,它就变成了:

template<typename T>
using EnableIfIntegral = int;

换句话说,模板类型只是普通类型 int 的简单别名。仅此而已。继续下一个声明:

template <typename T, EnableIfIntegral<T> = 0>
constexpr int Seconds(T n) {

这就变成了

template <typename T, int = 0>
constexpr int Seconds(T n) {

换句话说,一个简单的模板参数,一个默认为 0 的 int 常量。

仅此而已,仅此而已。这绝对没有任何作用,而这正是这里的预期结果。

第一个模板参数 T 从实际参数推导到 Seconds() 模板函数。然后第二个模板参数将 T 模板类型传递给 EnableIfIntegral 模板别名声明,希望如果所有的星星和月亮都正确对齐,它什么都不做。

现在,星星和月亮什么时候才能正确对齐?当推导的模板类型是某种整数类型或某种 enum 类型时。然后一切正常。

但是如果你做了一些傻事,比如:

std::string what_is_this;

Seconds(what_is_this);

对将要发生的事情的一个非常宽松的描述:Seconds 的第一个模板参数被推断为 std::string。到目前为止一切顺利,但我们已经注定失败,因为 Seconds 模板函数中的内容将无法处理 std::string 值。通常,这通常会导致典型的、难以辨认的(对于凡人而言)C++ 编译器错误消息。

但事情不会走到这一步。首先发生的是推导的 T 模板参数,现在是 std::string,被转发到 EnableIfIntegral,这个模板别名将无法解决。对于所有血淋淋的细节,请查看您最喜欢的 C++ 书籍中 std::enable_if 的作用。发生这种情况的具体细节不是很重要,关键是 Seconds() 模板本身的模板替换将失败。编译器将找不到适合此函数调用的 Seconds 模板。

这种情况通常会从您的编译器中生成更简单的错误消息。您的编译器的错误消息将非常基本,类似于“嘿,这里调用的这个 Seconds 模板是什么?我对此一无所知”。您将查看代码并意识到“愚蠢的我,我正在传递 std::string 但我需要传递一个整数值”。糟糕。

总的来说,这只是一种常见的方法,可以在出现问题且无法编译时减轻使用 C++ 库的痛苦。如果没有这个技巧,编译器将提示 time_internal::FromInt64 函数调用(基于问题中显示的代码),但该函数调用没有任何问题。问题实际上出在任何调用 Seconds 上,这就是问题所在,这种常用方法有助于编译器生成更好的错误消息。

关于c++ - 参数列表中的模板方法 "=0",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57618385/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com