I know this question has two answers - one very long and complicated and one rather short and simple. For now, I am interested in the latter.
I am coming from C#/.NET background and if you used it for a while (or Java) you will probably agree with me that whenever you use some BCL class or methods is relatively easy to deduce why certain overload is chosen by the compiler.
Simple example of 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);
If you haven't already figured out I am still trying to learn C++, so I will give a simple example and hopefully I will start feeling more comfortable reading std code after this question.
// 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<>());
}
I guess I will remind you of my disclaimer that I am new to C++ before I make some assumptions.
(&_Array)[_Size]
some way of helping compiler understand that parameter passed to a certain function (or function template) will be array (something like type_traits
)?is_heap(int*, int*)
since these are the argument types you are calling it with?Is (&_Array)[_Size] some way of helping compiler understand that parameter passed to a certain function (or function template) will be array (something like type_traits)?
_Ty (&_Array)[_Size]
is an array argument (a _Ty[_Size]
), passed by reference and named _Array
. It looks weird 'cos C, believe it or not. Nothing to do with type traits.
I don't really understand your second question, but the compiler picks the overload that best matches your arguments. The rules on what "best" means here are complex but described in the standard. If multiple overloads match equally, your call is ambiguous and the program will not compile. Templates do complicate this as they introduce many possible candidates by their very nature. I do agree that the template is likely to be instantiated here with _RanIt=int*
, and the result is a perfect match for your call.