Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带模板的lambda_C++_Templates_Lambda_C++11 - Fatal编程技术网

C++ 带模板的lambda

C++ 带模板的lambda,c++,templates,lambda,c++11,C++,Templates,Lambda,C++11,我目前正在做一些模板函数的练习。 我的任务是编写转换算法的实现。 我是这样做的,效果很好: template <class in, class out, class T> out stransform(in b, in e, out d, T p(const T&)) { while (b != e) *d++ = p(*b++); return d; } 这样我就得到了一个编译器错误,无法推断类型。 这是我不理解的事情,因为我在lambd

我目前正在做一些模板函数的练习。 我的任务是编写转换算法的实现。 我是这样做的,效果很好:

template <class in, class out, class T>
out stransform(in b, in e, out d, T p(const T&)) {
    while (b != e) 
        *d++ = p(*b++);
    return d;
}
这样我就得到了一个编译器错误,无法推断类型。 这是我不理解的事情,因为我在lambda中定义了两次T类型

我也检查了原始的转换函数,它正在使用。然后我检查了它的功能,很明显,它是用一个模板类为整个函数实现的。
这是用模板实现谓词的正确方法吗?

谓词通常是一个简单的模板参数:

template <class in, class out, class UnaryPredicate>
out stransform(in b, in e, out d, UnaryPredicate p); 
模板
out stransform(在b中,在e中,在d中,在p中);
这将接受指向函数、lambda和函数对象的指针。

tp(const T&)
是通过引用获取
T
的函数类型。您的lambda按值获取其参数

这应该行得通。不执行任何捕获的lambda可转换为普通函数

对于整个函数,它显然是用模板类实现的

略带保留适当的术语:
std::transform
是函数模板,而不是函数。更重要的是,在风格宣言中

template<class InputIterator, class OutputIterator, class Functor>
OutputIterator
transform(InputIterator begin, InputIterator end, OutputIterator out, Functor f);
然后将
inputierator
outputierator
推导出为
int*
Functor
int(*)(int)
,它们都不是类类型——更不用说模板类了,但我离题了。事实上,
transform
也可以声明

template<typename InputIterator, typename OutputIterator, typename Functor>
OutputIterator
transform(InputIterator begin, InputIterator end, OutputIterator out, Functor f);
模板
输出迭代器
变换(输入迭代器开始、输入迭代器结束、输出迭代器输出、函子f);

其中关键字
typename
对模板参数的性质更为清楚:它们是类型,具有任何性质。

@bamboon我猜是因为lambda不是函数,而是函数对象,因为它也可能保存状态(它是一个闭包,而不仅仅是一个函数)。请注意,不执行任何捕获的lambda可转换为普通函数(指针)。@spraff:但该转换未在MSVC2010中实现,因此根据编译器的不同,它可能无法工作。(更重要的是,转换是不必要的,并且可能效率低下)所以lambda的类型是一个隐式转换为函数指针的类?这种隐式转换无论如何不会在类型推断中被考虑。@访问者:lambda的类型是一个未知的类类型,它为定义的参数实现了
operator()
,并返回相同的返回类型。在特定情况下,如果lambda不捕获任何内容(并且只有在该情况下),它可以转换为具有相同签名的函数指针,但前提是lambda根本不捕获任何内容。但为什么要依赖于对函数指针的不必要转换,当你可以重新定义函子来处理函子和函数指针时?@jalf重新定义函子是一个更好的解决方案,我同意。如果不可变库代码出现此问题,则转换可以工作。@spraff:即使类型是可转换的,通过在模板中使用它,编译器也必须推导出
T
,在那个阶段,我认为它不能应用任何转换(除非lambda的类型是函数本身,而不是在没有捕获的情况下的函子)。
stransform (
    begin (vec1),
    end (vec1),
    back_inserter (vec2),
    [] (const double & x) -> double {
        return x * 10;
    });
template<class InputIterator, class OutputIterator, class Functor>
OutputIterator
transform(InputIterator begin, InputIterator end, OutputIterator out, Functor f);
// function declaration
int increment(int);

int array[] = { 0, 1, 2, 3, 4 };
transform(std::begin(array), std::end(array), std::begin(array), increment);
template<typename InputIterator, typename OutputIterator, typename Functor>
OutputIterator
transform(InputIterator begin, InputIterator end, OutputIterator out, Functor f);