std::make_pair、c++11 和显式模板参数
std::make_pair, c++11 and explicit template parameters
重新编辑:首先,这只是出于好奇,我知道 std::pair 或许多其他解决方案可以根除这个问题。
你能告诉我,下面这个问题的背后究竟是什么吗?此代码是一个在 c++03 上工作的简单示例,在 c++11 上失败。
std::pair<int*,int**> getsth(int* param)
{
return std::make_pair<int*,int**>(param, 0);
}
int main(int argc, char* argv[])
{
int* a = new int(1);
std::pair<int*,int**> par = getsth(a);
std::cout << *par.first;
return 0;
}
我知道如何修复它以与这里的两个标准兼容,但这让我很烦,我不知道,在这种情况下 make_pair 背后到底是什么。
谢谢!
已编辑:来自 Coliru 的编译错误消息:
main.cpp: In function 'std::pair<int*, int**> getsth(int*)':
main.cpp:8:47: error: no matching function for call to 'make_pair(int*&, int)'
return std::make_pair<int*,int**>(param, 0);
^
main.cpp:8:47: note: candidate is:
In file included from /usr/local/include/c++/4.9.2/bits/stl_algobase.h:64:0,
from /usr/local/include/c++/4.9.2/bits/char_traits.h:39,
from /usr/local/include/c++/4.9.2/ios:40,
from /usr/local/include/c++/4.9.2/ostream:38,
from /usr/local/include/c++/4.9.2/iostream:39,
from main.cpp:1:
/usr/local/include/c++/4.9.2/bits/stl_pair.h:276:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
make_pair(_T1&& __x, _T2&& __y)
^
/usr/local/include/c++/4.9.2/bits/stl_pair.h:276:5: note: template argument deduction/substitution failed:
main.cpp:8:47: note: cannot convert 'param' (type 'int*') to type 'int*&&'
return std::make_pair<int*,int**>(param, 0);
^
main.cpp:9:1: warning: control reaches end of non-void function [-Wreturn-type]
}
您需要删除 make_pair 的模板参数。 Here 是关于原因的更多信息。
此外,您应该将 nullptr
传递给 make_pair
,而不是 0。
发生右值引用。 C++03 中的 std::make_pair
具有签名
template< class T1, class T2 >
std::pair<T1,T2> make_pair( T1 t, T2 u );
在 C++11 中,它有
template< class T1, class T2 >
std::pair<V1,V2> make_pair( T1&& t, T2&& u );
V1
和 V2
(通常)是 std::decay<T1|T2>::type
。 C++14 添加了 constexpr
,但这确实与我们有关。
这意味着显式函数模板特化 std::make_pair<int*, int**>
在 C++03 中接受了 int*
和 int**
类型的参数,而 C++11 中的新参数接受 int*&&
和 int**&&
.
将 0
绑定到 int**&&
不是问题,但是 param
是一个左值,不能绑定到对 int*
的右值引用。这就是您的代码在 C++11 中爆炸的原因。
因此,
return std::make_pair<int*&, int**>(param, 0);
适用于 C++03 和 C++11——param
可以绑定到 int*&
,结果 std::pair<int*&, int**>
可以转换为 std::pair<int*, int**>
该函数在两个版本中都希望 return。
不过,这相当丑陋,而且 std::make_pair
并不是真的要以这种方式使用。作为@T.C。在评论中指出,如果您知道 std::pair
应该具有的类型,只需使用
return std::pair<int*, int**>(param, 0);
重新编辑:首先,这只是出于好奇,我知道 std::pair 或许多其他解决方案可以根除这个问题。
你能告诉我,下面这个问题的背后究竟是什么吗?此代码是一个在 c++03 上工作的简单示例,在 c++11 上失败。
std::pair<int*,int**> getsth(int* param)
{
return std::make_pair<int*,int**>(param, 0);
}
int main(int argc, char* argv[])
{
int* a = new int(1);
std::pair<int*,int**> par = getsth(a);
std::cout << *par.first;
return 0;
}
我知道如何修复它以与这里的两个标准兼容,但这让我很烦,我不知道,在这种情况下 make_pair 背后到底是什么。
谢谢!
已编辑:来自 Coliru 的编译错误消息:
main.cpp: In function 'std::pair<int*, int**> getsth(int*)':
main.cpp:8:47: error: no matching function for call to 'make_pair(int*&, int)'
return std::make_pair<int*,int**>(param, 0);
^
main.cpp:8:47: note: candidate is:
In file included from /usr/local/include/c++/4.9.2/bits/stl_algobase.h:64:0,
from /usr/local/include/c++/4.9.2/bits/char_traits.h:39,
from /usr/local/include/c++/4.9.2/ios:40,
from /usr/local/include/c++/4.9.2/ostream:38,
from /usr/local/include/c++/4.9.2/iostream:39,
from main.cpp:1:
/usr/local/include/c++/4.9.2/bits/stl_pair.h:276:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
make_pair(_T1&& __x, _T2&& __y)
^
/usr/local/include/c++/4.9.2/bits/stl_pair.h:276:5: note: template argument deduction/substitution failed:
main.cpp:8:47: note: cannot convert 'param' (type 'int*') to type 'int*&&'
return std::make_pair<int*,int**>(param, 0);
^
main.cpp:9:1: warning: control reaches end of non-void function [-Wreturn-type]
}
您需要删除 make_pair 的模板参数。 Here 是关于原因的更多信息。
此外,您应该将 nullptr
传递给 make_pair
,而不是 0。
发生右值引用。 C++03 中的 std::make_pair
具有签名
template< class T1, class T2 >
std::pair<T1,T2> make_pair( T1 t, T2 u );
在 C++11 中,它有
template< class T1, class T2 >
std::pair<V1,V2> make_pair( T1&& t, T2&& u );
V1
和 V2
(通常)是 std::decay<T1|T2>::type
。 C++14 添加了 constexpr
,但这确实与我们有关。
这意味着显式函数模板特化 std::make_pair<int*, int**>
在 C++03 中接受了 int*
和 int**
类型的参数,而 C++11 中的新参数接受 int*&&
和 int**&&
.
将 0
绑定到 int**&&
不是问题,但是 param
是一个左值,不能绑定到对 int*
的右值引用。这就是您的代码在 C++11 中爆炸的原因。
因此,
return std::make_pair<int*&, int**>(param, 0);
适用于 C++03 和 C++11——param
可以绑定到 int*&
,结果 std::pair<int*&, int**>
可以转换为 std::pair<int*, int**>
该函数在两个版本中都希望 return。
不过,这相当丑陋,而且 std::make_pair
并不是真的要以这种方式使用。作为@T.C。在评论中指出,如果您知道 std::pair
应该具有的类型,只需使用
return std::pair<int*, int**>(param, 0);