目前,要使用以下内容......
template< class ResultCollection, class Collection, typename Transformation >
ResultCollection Transform(const Collection& c, Transformation t)
{
ResultCollection result(c.size());
transform(c.begin(), c.end(), result.begin(), t);
return result;
}
...您需要提供返回类型:
auto result = Transform< std::vector<int> >( someInputCollection, [] (SomeType& element) { return ElementToInt(element); });
是否可以默认模板args,以便默认情况下你会得到一个包含lambda返回的任何类型元素的向量?
我得到了这个:
template< class Collection, typename Transformation, class ResultCollection = std::vector< std::result_of_t<Transformation> > >
ResultCollection Transform(const Collection& c, Transformation t)
{
ResultCollection result(c.size());
transform(c.begin(), c.end(), result.begin(), t);
return result;
}
但是这给了我这个:
C2783: 'ResultCollection Transform(const Collection &,Transformation)' : could not deduce template argument for 'ResultCollection'
而且我不确定如何解决它。
答案 0 :(得分:2)
您的代码存在两个问题。第一个缺少typename
s:
class ResultCollection = std::vector< typename std::iterator_traits<typename Collection::iterator>::value_type >
^^^^^^^^ ^^^^^^^^
但第二个是你传的错误类型!如果你的Transformation
实际上并没有改变集合的值类型,那么这一切都很好,但如果这样做会怎么样?
std::vector<char> collection;
auto result = Transform(collection, [](char c) { return std::string(c, 1); });
您需要生成的vector
包含Transformation
提供的类型:
class ResultCollection = std::vector<
std::result_of_t<Transformation(decltype(*std::declval<Collection>().begin()))>
>
而且,顺便说一下,如果结果类型不是默认构造的,该怎么办?你假设它在这里:
ResultCollection result(c.size());
可能想要这样做:
ResultCollection result;
result.reserve(c.size());
std::transform(c.begin(), c.end(), std::back_inserter(result), t);
或者真的:
ResultCollection result;
result.reserve(c.size());
for (const auto& elem : c) {
result.push_back(t(elem));
}
答案 1 :(得分:1)
您可以使用kennytm中this answer提供的function_traits
来获取lambda的返回类型并将其设置为默认值。使用它你会得到
template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
{};
// For generic types, directly use the result of the signature of its 'operator()'
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
enum { arity = sizeof...(Args) };
// arity is the number of arguments.
typedef ReturnType result_type;
template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
// the i-th argument is equivalent to the i-th tuple element of a tuple
// composed of those arguments.
};
};
template< class Collection, typename Transformation, class ResultCollection = std::vector< typename function_traits<Transformation>::result_type > >
ResultCollection Transform(const Collection& c, Transformation t)
{
ResultCollection result(c.size());
transform(c.begin(), c.end(), result.begin(), t);
return result;
}
你可以看到它在 Live Example
中运行