c++ - 对重载函数模板的模糊调用 - 即使一个更专业?

标签 c++ templates c++11 overloading

考虑以下几点:

#include <utility>

template <int N>
using size_ = std::integral_constant<int, N>; 

template <int From>
void f(size_<From>, size_<From+1> ) // (1)
{ }

template <int From, int To>   // (2)
void f(size_<From>, size_<To> )
{ }

int main()
{
    f(size_<0>{}, size_<1>{});
}

gcc 和 clang 都报告调用不明确。为什么?不是 (1)(2)更专业?

注意:我知道这很容易通过额外的 enable_if_t<(To > From+1)> 修复扔进(2) ,但我不认为我需要这样做。

最佳答案

毫不奇怪,CWG 问题中的一个类似示例解决了这个问题,即 #455 :

In case that one of the arguments is non-deuced then partial ordering should only consider the type from the specialization:

template<typename T> struct B { typedef T type; };

template<typename T> char* f3(T, T);                   // #7
template<typename T> long* f3(T, typename B<T>::type); // #8

char* p3 = f3(p3, p3); // #9

According to my reasoning #9 should yield ambiguity since second pair is (T, long*). The second type (i.e. long*) was taken from the specialization candidate of #8. EDG and GCC accepted the code. VC and BCC found an ambiguity.

ICC 和 VC++ 都会编译您的代码。根据目前的措辞,它们是正确的:每一对都独立处理,并且作为size_<From+1>使 From出现在非推导上下文中 ([temp.deduct.type]/(5.3)),推导必然失败,因此 size_<From+1>至少和size_<To>一样专业但反之亦然。因此重载 (1) 比 (2) 更专业。

因此 ICC 和 VC++(大概)处理每个推导对并得出结论,对于第二个推导对,size_<To>至少不像size_<From+1>那么专业.
Clang 和 GCC(大概)认为,对于 (1),From是从第一个参数推导出来的,因此不需要在 size_<To> 的第二对中推导出来至少和它的对手一样专业。

关于c++ - 对重载函数模板的模糊调用 - 即使一个更专业?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32335523/

相关文章:

c++ - 为什么 C++ 更喜欢这个模板方法而不是方法重载?

c++ - 这段代码的时间复杂度能否进一步降低?

c++ - 在 C++ 中为 vector 容器重载 [] 运算符时, undefined index 返回什么?

c++ - 以编程方式删除环境变量

c++ - 通过加入析构函数来等待异步工作是否安全?

c++ - 有没有更好的方法来通过模板用预先计算的值填充数组(用于运行时)?

c++ - 使用功能模板调用 C++ 类成员函数

c++ - 构造函数定义中的 void 是什么意思?

c++ - 将 php 函数 addslashes 移植到 c++ 的最快解决方案

c++ - 如何实现自定义模板排序功能?