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

Roger Ferrer Ibanez via cfe-dev cfe-dev at lists.llvm.org
Thu Nov 16 09:39:22 PST 2017


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.

Hope this answers your question.

Kind regards,
Roger

> -----Original Message-----
> From: cfe-dev [mailto:cfe-dev-bounces at lists.llvm.org] On Behalf Of
> Krzysztof Parzyszek via cfe-dev
> Sent: 16 November 2017 17:21
> To: Clang Dev
> Subject: [cfe-dev] Explicit template arguments in std::make_pair
> 
> Hi,
> 
> This simple program fails to compile with -std=c++11, but compiles ok
> with c++03. This seems consistent between libc++/libstdc++. Is this due
> to a change in the standard? What is the reason behind it?
> 
> 
> 
> #include <utility>
> 
> std::pair<int,unsigned> good(unsigned L) {
>    return std::make_pair(0, L);
> }
> 
> std::pair<int,unsigned> bad(unsigned L) {
>    return std::make_pair<int,unsigned>(0, L);
> }
> 
> 
> clang++ -c -std=c++11 pp.cpp -stdlib=libc++
> pp.cpp:8:10: error: no matching function for call to 'make_pair'
>    return std::make_pair<int,unsigned>(0, L);
>           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
> /w/c/org/bin/../include/c++/v1/utility:639:1: note: candidate function not
>        viable: no known conversion from 'unsigned int' to 'unsigned int
> &&' for
>        2nd argument
> make_pair(_T1&& __t1, _T2&& __t2)
> ^
> 1 error generated.
> 
> 
> -Krzysztof
> 
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> hosted by The Linux Foundation
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


More information about the cfe-dev mailing list