为什么enable_if_t需要有数据类型标识符和默认值?

发布于 2025-01-11 03:54:58 字数 2749 浏览 0 评论 0原文

我无法理解下面代码片段中的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

-小熊_ 2025-01-18 03:54:58

以下内容本身完全没问题:

template<class T, std::enable_if_t<std::is_integral_v<T>, bool>>
void fun(T value)
{
    std::cout << "\n In Integral version";
}

template<class T, std::enable_if_t<std::is_floating_point_v<T>, bool>>
void fun(T value)
{
    std::cout << "\n In Floating point version";
}

它的模板具有两个模板参数。当你想给他们打电话时,问题就出现了。如果您尝试像在 main 中那样调用它们:

int main()
{    
    fun(4);
    fun(4.4);
}

您将收到以下错误:

<source>:18:5: error: no matching function for call to 'fun'
    fun(4);
    ^~~
<source>:5:6: note: candidate template ignored: couldn't infer template argument ''
void fun(T value)
     ^
<source>:11:6: note: candidate template ignored: couldn't infer template argument ''
void fun(T value)
     ^
<source>:19:5: error: no matching function for call to 'fun'
    fun(4.4);
    ^~~
<source>:5:6: note: candidate template ignored: couldn't infer template argument ''
void fun(T value)
     ^
<source>:11:6: note: candidate template ignored: couldn't infer template argument ''
void fun(T value)
     ^

模板有 2 个模板参数。一个是 T,另一个是 bool 或替换失败。无法从函数参数推导出第二个参数,因此会出现错误。

考虑在 T==int 的情况下您会得到什么。 std::enable_if_t 只是一个别名。在您的情况下,对于 bool 或别名未定义:

template<int, bool>  // because int is integral
void fun(T value)
{
    std::cout << "\n In Integral version";
}

template<int, "substitution failure"> // because int is integral
void fun(T value)
{
    std::cout << "\n In Floating point version";
}

第二个是替换失败,因此重载解析选择第一个。它有两个模板参数。

第二个模板参数不用于任何用途,只是在条件为 false 时失败。您不希望用户调用

 fun<int,true>(42);

您希望调用者通过 via 调用它,

 fun(42);

因为显式指定 tempalte 参数将破坏 SFINAE 的全部目的。不要求调用者指定模板参数(以防无法推导模板参数)的方法是提供默认值。这就是K = trueK = false 也可以。由于您不必命名参数,因此以下内容也有效:

template<class T, std::enable_if_t<std::is_integral_v<T>, bool> = 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> = true>
void fun(T value)
{
    std::cout << "\n In Floating point version";
}

The following in itself is completely fine:

template<class T, std::enable_if_t<std::is_integral_v<T>, bool>>
void fun(T value)
{
    std::cout << "\n In Integral version";
}

template<class T, std::enable_if_t<std::is_floating_point_v<T>, bool>>
void fun(T value)
{
    std::cout << "\n In Floating point version";
}

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:

int main()
{    
    fun(4);
    fun(4.4);
}

You will get an error along the line of:

<source>:18:5: error: no matching function for call to 'fun'
    fun(4);
    ^~~
<source>:5:6: note: candidate template ignored: couldn't infer template argument ''
void fun(T value)
     ^
<source>:11:6: note: candidate template ignored: couldn't infer template argument ''
void fun(T value)
     ^
<source>:19:5: error: no matching function for call to 'fun'
    fun(4.4);
    ^~~
<source>:5:6: note: candidate template ignored: couldn't infer template argument ''
void fun(T value)
     ^
<source>:11:6: note: candidate template ignored: couldn't infer template argument ''
void fun(T value)
     ^

The templates have 2 template arguments. One is T the other is either a bool 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 for bool or the alias is not defined:

template<int, bool>  // because int is integral
void fun(T value)
{
    std::cout << "\n In Integral version";
}

template<int, "substitution failure"> // because int is integral
void fun(T value)
{
    std::cout << "\n In Floating point version";
}

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 call

 fun<int,true>(42);

You want the caller to call it via

 fun(42);

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:

template<class T, std::enable_if_t<std::is_integral_v<T>, bool> = 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> = true>
void fun(T value)
{
    std::cout << "\n In Floating point version";
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文