我有一个实用函数,用于根据函子转换可迭代对象:
template<typename Iterable, typename Functor>
auto transform(Iterable const& input, Functor&& transformer) -> std::vector<decltype(transformer(*input.cbegin()))>
{
std::vector<decltype(transformer(*input.cbegin()))> output;
std::for_each(
std::cbegin(input),
std::cend(input),
[&output, &transformer](auto const& m) { output.emplace_back(transformer(m)); });
return output;
}
void test_transform()
{
std::vector<int> ints { 10, 20, 30 };
auto transformer = [](int i) { return std::to_string(i + 1); };
std::vector<std::string> strs = VectorUtil::transform(ints, transformer);
for (std::string s : strs) { std::cout << s << std::endl; }
}
必须将返回类型写两次是相当难看的。有没有办法给其中一个命名:
decltype(transformer(*input.cbegin()))
或者
std::vector<decltype(transformer(*input.cbegin()))>
那么它可以重复使用吗?
最漂亮的选择是完全删除返回类型并声明它
auto
,这意味着该函数将推导返回类型。对于您的情况来说,这很可能没问题,但也许您不能这样做。如果您确实坚持要声明返回类型,则仍然可以选择使用别名模板来简化此操作。
std::result_of
或者std::invoke_result
没有用,因为它们没有给你一个漂亮而简短的返回类型,这似乎就是这里的重点。这样的别名模板可以按如下方式使用:
分解类型的一种方法是将其作为默认模板参数: