为什么enable_if_t需要有数据类型标识符和默认值?
我无法理解下面代码片段中的 2 个注释代码行与它们前面的行有何不同?有没有一种简单的方法可以理解注释行的含义与它们前面的行的含义?我无法在脑海中说出如何阅读注释行及其旁边的行。有人可以解释一下吗?请不要向我指出文档。我在那里度过了一段时间,但我仍然不清楚,否则我不会在这里发布这个问题。
#include <iostream>
#include <type_traits>
//template<class T, std::enable_if_t<std::is_integral_v<T>, bool>>
template<class T, std::enable_if_t<std::is_integral_v<T>, bool> K = true>
void fun(T value)
{
std::cout << "\n In Integral version";
}
//template<class T, std::enable_if_t<std::is_floating_point_v<T>, bool>>
template<class T, std::enable_if_t<std::is_floating_point_v<T>, bool> K = true>
void fun(T value)
{
std::cout << "\n In Floating point version";
}
int main()
{
fun(4);
fun(4.4);
}
当我使用注释代码时会显示以下错误,但我不知道它们的含义或上面的代码如何解决它们。
Error(s):
2044199993/source.cpp: In function ‘int main()’:
2044199993/source.cpp:22:10: error: no matching function for call to ‘fun(int)’
fun(4);
^
2044199993/source.cpp:8:6: note: candidate: template<class T, typename std::enable_if<is_integral_v<T>, bool>::type <anonymous> > void fun(T)
void fun(T value)
^~~
2044199993/source.cpp:8:6: note: template argument deduction/substitution failed:
2044199993/source.cpp:22:10: note: couldn't deduce template parameter ‘<anonymous>’
fun(4);
^
2044199993/source.cpp:15:6: note: candidate: template<class T, typename std::enable_if<is_floating_point_v<T>, bool>::type <anonymous> > void fun(T)
void fun(T value)
^~~
2044199993/source.cpp:15:6: note: template argument deduction/substitution failed:
2044199993/source.cpp:22:10: note: couldn't deduce template parameter ‘<anonymous>’
fun(4);
^
2044199993/source.cpp:23:12: error: no matching function for call to ‘fun(double)’
fun(4.4);
^
2044199993/source.cpp:8:6: note: candidate: template<class T, typename std::enable_if<is_integral_v<T>, bool>::type <anonymous> > void fun(T)
void fun(T value)
^~~
2044199993/source.cpp:8:6: note: template argument deduction/substitution failed:
2044199993/source.cpp:23:12: note: couldn't deduce template parameter ‘<anonymous>’
fun(4.4);
^
2044199993/source.cpp:15:6: note: candidate: template<class T, typename std::enable_if<is_floating_point_v<T>, bool>::type <anonymous> > void fun(T)
void fun(T value)
^~~
2044199993/source.cpp:15:6: note: template argument deduction/substitution failed:
2044199993/source.cpp:23:12: note: couldn't deduce template parameter ‘<anonymous>’
fun(4.4);
^
I am unable to understand how the 2 commented code lines in below snippet are different than the lines just ahead of them? Is there an easy way to understand the meaning of the commented lines vs the meaning of lines just ahead of them? I am unable to speak in my mind as how to read the commented line and the line next to it. Could anyone please explain? And don't point me to the documentation please. I have spent time there and still its not clear to me else i wouldn't be posting this question here.
#include <iostream>
#include <type_traits>
//template<class T, std::enable_if_t<std::is_integral_v<T>, bool>>
template<class T, std::enable_if_t<std::is_integral_v<T>, bool> K = true>
void fun(T value)
{
std::cout << "\n In Integral version";
}
//template<class T, std::enable_if_t<std::is_floating_point_v<T>, bool>>
template<class T, std::enable_if_t<std::is_floating_point_v<T>, bool> K = true>
void fun(T value)
{
std::cout << "\n In Floating point version";
}
int main()
{
fun(4);
fun(4.4);
}
following errors are shown when i use commented code and i dont know what they mean or how the above code resolves them.
Error(s):
2044199993/source.cpp: In function ‘int main()’:
2044199993/source.cpp:22:10: error: no matching function for call to ‘fun(int)’
fun(4);
^
2044199993/source.cpp:8:6: note: candidate: template<class T, typename std::enable_if<is_integral_v<T>, bool>::type <anonymous> > void fun(T)
void fun(T value)
^~~
2044199993/source.cpp:8:6: note: template argument deduction/substitution failed:
2044199993/source.cpp:22:10: note: couldn't deduce template parameter ‘<anonymous>’
fun(4);
^
2044199993/source.cpp:15:6: note: candidate: template<class T, typename std::enable_if<is_floating_point_v<T>, bool>::type <anonymous> > void fun(T)
void fun(T value)
^~~
2044199993/source.cpp:15:6: note: template argument deduction/substitution failed:
2044199993/source.cpp:22:10: note: couldn't deduce template parameter ‘<anonymous>’
fun(4);
^
2044199993/source.cpp:23:12: error: no matching function for call to ‘fun(double)’
fun(4.4);
^
2044199993/source.cpp:8:6: note: candidate: template<class T, typename std::enable_if<is_integral_v<T>, bool>::type <anonymous> > void fun(T)
void fun(T value)
^~~
2044199993/source.cpp:8:6: note: template argument deduction/substitution failed:
2044199993/source.cpp:23:12: note: couldn't deduce template parameter ‘<anonymous>’
fun(4.4);
^
2044199993/source.cpp:15:6: note: candidate: template<class T, typename std::enable_if<is_floating_point_v<T>, bool>::type <anonymous> > void fun(T)
void fun(T value)
^~~
2044199993/source.cpp:15:6: note: template argument deduction/substitution failed:
2044199993/source.cpp:23:12: note: couldn't deduce template parameter ‘<anonymous>’
fun(4.4);
^
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以下内容本身完全没问题:
它的模板具有两个模板参数。当你想给他们打电话时,问题就出现了。如果您尝试像在
main
中那样调用它们:您将收到以下错误:
模板有 2 个模板参数。一个是
T
,另一个是bool
或替换失败。无法从函数参数推导出第二个参数,因此会出现错误。考虑在
T==int
的情况下您会得到什么。std::enable_if_t
只是一个别名。在您的情况下,对于bool
或别名未定义:第二个是替换失败,因此重载解析选择第一个。它有两个模板参数。
第二个模板参数不用于任何用途,只是在条件为
false
时失败。您不希望用户调用您希望调用者通过 via 调用它,
因为显式指定 tempalte 参数将破坏 SFINAE 的全部目的。不要求调用者指定模板参数(以防无法推导模板参数)的方法是提供默认值。这就是
K = true
。K = false
也可以。由于您不必命名参数,因此以下内容也有效:The following in itself is completely fine:
Its templates with two template arguments. The issue arises when you want to call them. If you try to call them like you do in
main
:You will get an error along the line of:
The templates have 2 template arguments. One is
T
the other is either abool
or a substitution failure. The second argument cannot be deduced from the function parameters, hence the error.Consider what you get in case of
T==int
.std::enable_if_t
is just an alias. In your case either forbool
or the alias is not defined:The second is a substitution failure, so overload resolution picks the first. And it has two template arguments.
The second template argument is not used for anything but to fail when the condition is
false
. You do not want the user to callYou want the caller to call it via
because explicitly specifying the tempalte argument would defeat the whole purpose of SFINAE here. The way to not reqiure the caller to specify the template argument in case it cannot be deduced is to supply a default. And thats the
K = true
.K = false
would work as well. And as you do not have to name the argument the following works as well: