qea*_*tzy 4 c++ lambda templates c++11 type-deduction
我想要实现的是一个接受三个参数的makeSet()函数,一对迭代器和一个转换值的函数.
一个用例可以是从一系列值创建一个集合并进行转换,例如,将a转换std::map<K,V>为std::set<std::pair<V,K>>.
客户端代码可能看起来像
auto s = makeSet(hash.begin(), hash.end(),
[](std::pair<int,int> x) { return std::make_pair(x.second, x.first); });
Run Code Online (Sandbox Code Playgroud)
我目前的尝试如下,
// (commented code are some other *failed* attempt).
template <typename Iterator,
typename T = typename std::iterator_traits<Iterator>::value_type,
template<typename ... > class Monad, typename R >
// typename R, typename Monad = std::function<R(T)> >
std::set<R> makeSet(Iterator first, Iterator last, Monad<R,T> f) {
std::set<R> res;
for (; first != last; ++first) res.insert(f(*first));
return res;
}
Run Code Online (Sandbox Code Playgroud)
但遗憾的是不起作用.问题似乎无法推断R.
有没有解决方案或解决方法?如果你能告诉我正确的方法,我将非常感激.
lambda表达式的类型是未命名的类类型(它的闭包类型),而不是std::function.因此,您无法推断std::function或推断Monad它.
您最好的选择是执行标准库的操作,并简单地接受任何内容作为谓词:
template <
class Iterator,
class UnaryFunction
>
auto makeSet(Iterator first, Iterator last, UnaryFunction f) -> std::set<decltype(f(*first))>
{
std::set<decltype(f(*first))> res;
for (; first != last; ++first) res.insert(f(*first));
return res;
}
Run Code Online (Sandbox Code Playgroud)
请注意,您可能需要包裹decltype在std::remove_reference和/或std::remove_cv覆盖所有角落的情况下(或者,所建议@Yakk,std::decay).
另外,为避免重新发明轮子,您可能需要查看Boost.Range库.
| 归档时间: |
|
| 查看次数: |
240 次 |
| 最近记录: |