函数模板中返回类型的模板实参演绎
template argument deduction of return type in function template
给出以下最小示例:
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <set>
#include <vector>
template<typename ContainerOut, typename X, typename Y, typename ContainerIn>
ContainerOut Map( const ContainerIn& xs, const std::function<Y( const X& )>& f )
{
ContainerOut ys;
std::transform( begin( xs ), end( xs ), std::inserter( ys, end( ys ) ), f );
return ys;
}
struct Foo {
Foo( int val ) : val_( val ) {}
int val_;
};
std::set<int> FooValsToIntSet( const std::list<Foo>& foos )
{
//Map<std::set<int>, Foo, int>
return Map( foos, []( const Foo& foo )
{
return foo.val_;
} );
}
int main()
{
std::list<Foo> foos = { 1, 2, 2, 3 };
std::set<int> vals = FooValsToIntSet( foos );
for ( auto& v : vals )
std::cout << v << std::endl;
}
行return Map( foos, []( const Foo& foo )
不被我测试的编译器接受。
如果我显式地写出模板参数,它就可以工作了:
return Map<std::set<int>, Foo, int>( foos, []( const Foo& foo )
但我不明白为什么这是必要的。有没有办法避免这种冗长?
嗯,编译器没有办法推断出ContainerOut
类型——返回类型不参与类型推断。但是,您可以让编译器推断除返回类型以外的所有内容。作为旁注,至少在本例中,没有理由使用std::function
—它只是增加了不必要的开销。
这样会更好:
template<typename ContainerOut, typename ContainerIn, typename F>
ContainerOut Map( const ContainerIn& xs, F&& f )
{
ContainerOut ys;
std::transform( begin( xs ), end( xs ), std::inserter( ys, end( ys ) ), f );
return ys;
}
然后你可以把它命名为
return Map<std::set<int>>( foos, []( const Foo& foo )
{
return foo.val_;
} );
您似乎不需要 Map()
内部的实际模板参数,因此您可以将函数对象作为单个参数扣除:
template<typename ContainerOut, typename ContainerIn, typename Function>
ContainerOut Map( const ContainerIn& xs, const Function& f )
{
...
}
这也是STL算法获取谓词的方式
相关文章:
- 非类型引用形参/实参
- 成员函数指针的模板实参演绎
- 函数和函数作为模板函数的实参
- Const到非Const指针模板实参的转换
- 传递boost::函数,该函数接受一个模板实参作为默认为NULL的形参
- 当实参是初始化列表而形参是引用时,重载解析
- 函数模板中返回类型的模板实参演绎
- ostream_iterator的模板实参-每个元素都是pair
- c++——关于使用默认实参的困惑
- std::shared_ptr、继承和模板实参演绎的问题
- 将操作符转换为模板实参的特化
- 使用模板模板形参时,模板实参推导失败
- 带有const实参的c++构造函数
- c++ 17中关于类模板实参演绎的问题
- 用const实参重载实参演绎的c++模板函数
- 定义任何成员函数指针的别名中的模板实参演绎
- c++中转换函数模板实参演绎的含义
- 函数指针的形参类型的模板实参演绎涉及未演绎的形参包
- 替换在模板实参演绎中是如何工作的
- 从函数指针的实参中演绎出c++模板类型