C++ 模板,类型推断不足
我正在玩Streamsála Java 8的一个实现。我希望编译器接受以下代码C++ 模板,类型推断不足,c++,templates,template-argument-deduction,C++,Templates,Template Argument Deduction,我正在玩Streamsála Java 8的一个实现。我希望编译器接受以下代码 Stream stream; stream .map ([] (int x) { return 10*x; }) // error .forEach ([] (int x) { cout << x << " ";}); 流; 流动 .map([](int x){return 10*x;})//错误 .forEach([](int x){cout映射
Stream stream;
stream
.map ([] (int x) { return 10*x; }) // error
.forEach ([] (int x) { cout << x << " ";});
流;
流动
.map([](int x){return 10*x;})//错误
.forEach([](int x){cout映射){
返回MappedStream(*this,mapping);
}
};
模板
类MappedStream
:公共流
{
公众:
MappedStream(流和源,
函数映射)
{}
};
int main(int argc,字符**argv)
{
溪流;
流动
.map([](int x){return 10*x;})
//XXXXXlambda不是std::function
,您几乎不想将std::function
用作函数模板的参数,因为可以推断其中模板参数的唯一方法是调用方构造一个std::function
并将其传入
相反,接受任何函数对象,然后计算返回类型:
template <typename F, typename Re = std::result_of_t<F&(T)>>
MappedStream<T,Re> map (F mapping) {
return MappedStream<T,Re>(*this, mapping);
}
模板
MappedStream映射(F映射){
返回MappedStream(*this,mapping);
}
一般来说,应该避免不必要的类型擦除。MappedStream
的类型不依赖于所使用的映射器,这可能很有用,因此在内部存储std::function
是合理的,但是forEach
可能应该是一个接受任何函数对象的模板,而不仅仅是std::function
你可以这样做,但我猜它破坏了你的设计(你似乎喜欢std::function
s),你无法从lambda推断std::function
。
.map<int> ([] (int x) { return 10*x; })
#include <iostream>
#include <functional>
using namespace std;
template <typename Tfrom, typename Tto> class MappedStream;
template <typename T>
class Stream
{
public:
void forEach(function< void(T) > action)
{}
template <typename Re>
MappedStream<T,Re> map (function < Re(T)> mapping) {
return MappedStream<T,Re>(*this, mapping);
}
};
template <typename Tfrom, typename Tto>
class MappedStream
: public Stream<Tto>
{
public:
MappedStream(Stream<Tfrom> & source,
function <Tto(Tfrom)> mapping)
{}
};
int main(int argc, char **argv)
{
Stream<int> stream;
stream
.map<int> ([] (int x) { return 10*x; })
// XXXXX <- how to get rid of this?
.forEach ([] (int x) { cout << x << " ";});
return 0;
}
template <typename F, typename Re = std::result_of_t<F&(T)>>
MappedStream<T,Re> map (F mapping) {
return MappedStream<T,Re>(*this, mapping);
}