Wyz*_*a-- 5 c++ templates c++11 type-deduction c++14
我有一个函数模板,它取一个std::pair对的类型之一的值.我想使用a std::map作为pair参数的条目来调用此函数.
#include <map>
#include <utility>
template <typename T1, typename T2>
void do_stuff(std::pair<T1, T2> const &pair, T1 const &val) {
// Imagine that this does something important...
}
int main() {
std::map<int, float> foo { { 0, 0.0 } };
do_stuff(*foo.begin(), 0);
}
Run Code Online (Sandbox Code Playgroud)
这无法编译,因为地图条目std::pair<const int, float>的类型是,因此类型推导T1具有冲突类型:const int通过pair参数,并int通过val参数.
test.cc: In function ‘int main()’:
test.cc:12:27: error: no matching function for call to ‘do_stuff(std::pair<const int, float>&, int)’
do_stuff(*foo.begin(), 0);
^
test.cc:5:6: note: candidate: template<class T1, class T2> void do_stuff(const std::pair<_T1, _T2>&, const T1&)
void do_stuff(std::pair<T1, T2> const &pair, T1 const &val) {
^~~~~~~~
test.cc:5:6: note: template argument deduction/substitution failed:
test.cc:12:27: note: deduced conflicting types for parameter ‘const T1’ (‘const int’ and ‘int’)
do_stuff(*foo.begin(), 0);
^
Run Code Online (Sandbox Code Playgroud)
解决这场冲突的最佳方法是什么?理想情况下,我希望T1将其推断为int,但const int如果实现起来更为直接,则可以.
我发现我可以通过使用解决的错误std::remove_const或std::decay对类型val参数:
void do_stuff(std::pair<T1, T2> const &pair, typename std::remove_const<T1>::type const &val) {
Run Code Online (Sandbox Code Playgroud)
但我不知道哪一个更合适,或者是否有其他解决方案更好.
一种解决方案是使用std::add_const而不是const直接使用关键字.
通过模板的往返可以防止通过此参数类型进行类型推导:
#include <map>
#include <type_traits>
#include <utility>
template< class T1, class T2 >
void do_stuff( std::pair<T1, T2> const& pair, std::add_const_t<T1>& val )
{
// Imagine that this does something important...
(void) pair; (void) val;
}
auto main()
-> int
{
std::map<int, float> foo { { 0, 0.0f } };
do_stuff(*foo.begin(), 0);
}
Run Code Online (Sandbox Code Playgroud)