[cfe-dev] Explicit template arguments in std::make_pair

John McCall via cfe-dev cfe-dev at lists.llvm.org
Thu Nov 16 14:53:58 PST 2017


> On Nov 16, 2017, at 5:38 PM, Krzysztof Parzyszek <kparzysz at codeaurora.org> wrote:
> 
> Thanks all, that explains it.
> 
> I do provide explicit arguments sometimes when the object types aren't quite what I want the compiler to use, for example:
>  int x;
>  unsigned y;
>  std::make_pair<int,int>(x, y)
> instead of
>  std::make_pair(x, int(y)).
> 
> I suppose the latter may be the preferred version in the recent C++.

You can also just use std::pair<int,int>(x,y) if you're going to declare both arguments.

John.

> 
> -Krzysztof
> 
> 
> On 11/16/2017 2:34 PM, John McCall wrote:
>>> On Nov 16, 2017, at 12:39 PM, Roger Ferrer Ibanez via cfe-dev <cfe-dev at lists.llvm.org> wrote:
>>> Hi Krzysztof,
>>> 
>>> The reason is that in C++03 make_pair looked like this
>>> 
>>>    template <class T1, class T2>
>>>    pair<T1, T2> make_pair(T1 x, T2 y);
>>> 
>>> while in C++11 onwards looks like this
>>> 
>>>     template <class T1, class T2>
>>>     pair<V1, V2> make_pair(T1&& x, T2&& y)
>>> 
>>> where in libcxx (similarly for libstdc++) V1 and V2 are implemented like
>>> 
>>>     pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type>
>>> 
>>> because the C++ standard dictates a more sophisticated (compile-time computed) type for V1 and V2.
>>> 
>>> This implies that if you define T1 and T2 in the template-argument list of the function call, you are always going to get rvalue references in the parameter types (in your example 'int&&' and 'unsigned int&&' respectively).
>>> Conversely, if you let template-argument deduction to infer T1 and T2, it will infer
>>> 
>>>  std::pair<int, unsigned int> std::make_pair<int, unsigned int &>(int &&, unsigned int &);
>>> 
>>> because of the C++11 rules about type deduction involving parameter types of the form Type&&.
>>> 
>>> I'm not an expert in this area but this behaviour looks to me as expected and matches the C++ view of generic programming in which you should not constraint (in this case using template-arguments) if not needed.
>> More generally, the C++ standard library guarantees that specific expression forms will compile and have certain static and dynamic properties.  If there isn't a listed expression form with explicit template arguments, they're not portably allowed, and including them means you're exceeding the guarantees of the standard library just as much as you would be if you tried to forward-declare std::basic_string, or took the address of std::sort, or spelled out a concrete result type for std::vector<bool>::operator[].
>> John.
> 
> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation




More information about the cfe-dev mailing list