如何让编译器推导出模板的返回类型? [英] How can I let the compiler deduce the return type of a template?
问题描述
我来自Haskell,目前正在修改C ++ 11,看看它能做什么。我的一个玩具是一个小模板,试图模仿Haskell map
函数,即它需要一个容器 X
和将 X
映射到 Y
并生成 Y
。我知道我可以很容易地使用 std :: transform
,但这将破坏乐趣。
右现在,我的模板看起来像这样:
模板< typename T,typename U>
void myMap(const T& input,
U& output,
std :: function< typename U :: value_type(typename T :: value_type)> f);
现在,我的问题是:是否可以调整签名,通过引用(第二个参数)我通过返回值产生一个新的容器,但编译器可以推导出返回类型?类似
模板< typename T,typename U>
U myMap(const T& input,
std :: function< typename U :: value_type(typename T :: value_type)> f);
不能调用
std :: vector< int> x = {1,2,3,4};
std :: list< bool> y = myMap(x,[](int x){return x%2 == 0;});
...至少Clang无法在这里推导出返回类型。
我的一个想法是,鉴于输入容器类型和函数类型是已知的,你可以从中构造输出类型。也就是说例如
模板< typename C,typename T,typename U>
C< U> myMap(const C< T& input,
std :: function< U(T)> f);
... alas 您可能正在寻找此语法 C< U>
甚至似乎不是有效的语法。我不知道我是否需要正确的 decltype
童话尘埃,如
#include< algorithm&
#include< functional>
#include< type_traits>
#include< list>
模板
<
template< typename,typename ...> class Container,
typename InType,
typename FuncType,
typename ... Rest
>
auto myMap(const Container FuncType func) - >
Container< decltype(func(std :: declval< InType>())),Rest ...>
{
Container< decltype(func(std :: declval< InType>())),Rest ...>结果;
std :: transform(std :: begin(container),
std :: end(container),
std :: back_inserter(result),
func);
return result;
}
虽然我不建议在任何真正的项目中使用这种风格的代码。 / p>
I'm coming from Haskell and currently tinker with C++11 to see what it can do. One of my toys is a small template which attempts to imitate the Haskell map
function, i.e. it takes a container of values of X
and a function mapping an X
to a Y
and yields a container of values of Y
. I know that I could easily do that using std::transform
, but that would spoil the fun.
Right now, my template looks like this:
template <typename T, typename U>
void myMap( const T &input,
U &output,
std::function<typename U::value_type (typename T::value_type)> f );
Now, my qustion is: is it possible to adjust the signature so that instead of taking the output container by reference (the second argument) I yield a new container via the return value and yet the compiler can deduce the return type? Something like
template <typename T, typename U>
U myMap( const T &input,
std::function<typename U::value_type (typename T::value_type)> f );
unfortunately cannot be called like
std::vector<int> x = { 1, 2, 3, 4 };
std::list<bool> y = myMap( x, []( int x ) { return x % 2 == 0; } );
...at least Clang fails to deduce the return type here.
One idea I had was that given that the input container type and the function type is known, you could construct the output type from that. I.e. something like
template <typename C, typename T, typename U>
C<U> myMap( const C<T> &input,
std::function<U (T)> f );
...but alas C<U>
doesn't even seem to be valid syntax. I wonder if I just need the right decltype
fairy dust as was the case in this question.
You are probably looking for this syntax
#include <algorithm>
#include <functional>
#include <type_traits>
#include <list>
template
<
template<typename, typename...> class Container,
typename InType,
typename FuncType,
typename... Rest
>
auto myMap (const Container<InType, Rest...>& container,
FuncType func) ->
Container<decltype(func(std::declval<InType>())), Rest...>
{
Container<decltype(func(std::declval<InType>())), Rest...> result;
std::transform(std::begin(container),
std::end(container),
std::back_inserter(result),
func);
return result;
}
though I would not recommend using this style of code in any real project.
这篇关于如何让编译器推导出模板的返回类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!