C++ 模板,类型推断不足

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映射

我正在玩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映射){
返回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);
}