我知道这个问题有两个答案-一个很长很复杂,而另一个很短很简单。目前,我对后者感兴趣。
我来自C#/。NET背景,如果您使用了一段时间(或Java),您可能会同意我的观点,即每当您使用某些BCL类或方法时,相对容易推断出为什么选择了某些重载。编译器。
C#的简单示例
// lets imagine we have this somewhere in our code
Contract.Requires(e != null);
// we check who implements this method ...
public static void Requires(bool condition); // <-- observing the call its pretty obvious that this method will be chosen instead of the others
public static void Requires<TException>(bool condition, string userMessage) where TException : Exception;
public static void Requires<TException>(bool condition) where TException : Exception;
public static void Requires(bool condition, string userMessage);
[如果您还没有发现我仍在尝试学习C ++,那么我将举一个简单的例子,希望我在此问题之后开始感到更轻松地阅读标准代码。
// we have this call
int ints[5];
std::is_heap(std::begin(ints), std::end(ints));
// first method I tried to unwind was std::begin and std::end
// and this is what I got from Visual Studio as suggestion (and later confirmed by runtime)
template <class _Ty, size_t _Size>
_NODISCARD constexpr _Ty* begin(_Ty (&_Array)[_Size]) noexcept {
return _Array;
}
template <class _Ty, size_t _Size>
_NODISCARD constexpr _Ty* end(_Ty (&_Array)[_Size]) noexcept {
return _Array + _Size;
}
// then I checked std::is_heap and I got
template <class _RanIt>
_NODISCARD bool is_heap(_RanIt _First, _RanIt _Last) { // test if range is a heap ordered by operator<
return _STD is_heap(_First, _Last, less<>());
}
我想我会提醒您我的免责声明,在做出一些假设之前,我是C ++的新手。
(&_Array)[_Size]
是否可以帮助编译器理解传递给某个函数(或函数模板)的参数将是数组(类似于type_traits
)?is_heap(int*, int*)
之类的东西,因为这些是参数您用来呼叫的类型?(&_ Array)[_ Size]是否可以帮助编译器理解传递给某个函数(或函数模板)的参数将是数组(类似于type_traits)?
_Ty (&_Array)[_Size]
是一个数组参数(一个_Ty[_Size]
),通过引用传递并命名为_Array
。信不信由你,它看起来很奇怪。与类型特征无关。
我不太了解您的第二个问题,但是编译器会选择与您的参数最匹配的重载。关于“最佳”的含义的规则很复杂,但在标准中有所描述。如果多个重载均等地匹配,则您的调用是模棱两可的,程序将无法编译。模板的确因其本身的性质而引入了[[many]]个可能的候选者,因此确实使这变得复杂。我确实同意模板可能会在此处用_RanIt=int*
实例化,并且结果与您的通话非常匹配。