是什么导致这两个函数模板之间的重载失败? [英] What makes the overload fail between these two function templates?

查看:60
本文介绍了是什么导致这两个函数模板之间的重载失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个非常简短的例子.

Below is the pretty short example.

#include <utility>

template<typename T, typename = void>
struct A {};

template<typename T, typename U>
void f(A<std::pair<T,U>>) {}

template<typename U>
void f(A<std::pair<int,U>, std::enable_if_t<std::is_same_v<int,U>>>) {}

int main() {
  A<std::pair<int, int>> x;
  f(x);
}

错误很明显

uffa.cpp: In function ‘int main()’:                                                                                                                                                                                                                           
uffa.cpp:22:4: error: call of overloaded ‘f(A<std::pair<int, int> >&)’ is ambiguous                                                                                                                                                                           
   22 |   f(x);                                                                                                                                                                                                                                                
      |   ~^~~                                                                                                                                                                                                                                                 
uffa.cpp:10:6: note: candidate: ‘void f(A<std::pair<_T1, _T2> >) [with T = int; U = int]’                                                                                                                                                                     
   10 | void f(A<std::pair<T,U>>) {}                                                                                                                                                                                                                           
      |      ^                                                                                                                                                                                                                                                 
uffa.cpp:18:6: note: candidate: ‘void f(A<std::pair<int, U>, typename std::enable_if<is_same_v<int, U>, void>::type>) [with U = int; typename std::enable_if<is_same_v<int, U>, void>::type = void]’                                                          
   18 | void f(A<std::pair<int,U>, std::enable_if_t<std::is_same_v<int,U>>>) {}                                                                                                                                                                                
      |      ^

但我不明白为什么在第二个重载中将 int 作为固定模板参数并没有使它更专业化.毕竟,如果我从中删除 , std::enable_if_t<std::is_same_v<int,U>> ,那么它首选.

But I don't understand why having int as a fixed template argument in the second overload doesn't make it more specialized. After all, if I remove , std::enable_if_t<std::is_same_v<int,U>> from it, then it is preferred.

推荐答案

即使这是 ,我将提供一个外行的解释.

Even though this is language-lawyer, I'm going to provide a layman explanation.

是的,第二个重载将 pair 的第一个参数固定为 int,而第一个没有.

Yes, the second overload fixes the first parameter of pair as int, while the first one doesn't.

但是,另一方面,第一个重载将A第二个参数固定为void,而第二个没有.

But, on the other hand, the first overload fixes the second parameter of A as void, while the second one doesn't.

你的功能等同于那些:

template <typename T, typename U>
void f(A<std::pair<T, U>, void>) {}

template <typename U>
void f(A<std::pair<int,U>, blah-blah<U>>) {}

所以他们中没有一个比另一个更专业.

So none of them is more specialized than the other.

如果您使用更传统的 SFINAE,代码将起作用:

The code will work if you use more a conventional SFINAE:

template<typename U, std::enable_if_t<std::is_same_v<U, int>, std::nullptr_t> = nullptr>
void f(A<std::pair<int,U>>) {}

或 C++20 概念:

Or C++20 concepts:

template <std::same_as<int> U>
void f(A<std::pair<int,U>>) {}

这篇关于是什么导致这两个函数模板之间的重载失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆