STL:卷积两个unary_function参数

whe*_*ies 0 c++ templates stl

使用VS2005在Windows上工作,并努力理解我得到的错误消息.如果以前问过这个问题,我很抱歉.我找不到它.

我正在测试的是:

#include <functional>
using std::unary_function;

template<typename F, typename G>
struct UnaryConvolution : unary_function<typename G::argument_type,typename F::result_type>{
    UnaryConvolution(const F &_f, const G &_g) : m_F(_f), m_G(_g){}

    result_type operator()(const argument_type &_arg){
        return m_F( m_G( _arg ) );
    }

    F m_F;
    G m_G;
};
Run Code Online (Sandbox Code Playgroud)

单元测试我写过:

using std::bind2nd;
using std::equal_to;
using std::less;

bool unaryConvolution_test(){
    UnaryConvolution obj(bind2nd( equal_to<bool>(), true ), bind2nd( less<int>(), 5 ));

    return obj( 3 );
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误:

  1. 错误C2955:'UnaryConvolution':使用类模板需要模板参数列表
  2. 错误C3848:具有'UnaryConvolution'类型的表达式会丢失一些const-volatile限定符,以便调用'_Result UnaryConvolution :: operator()(const _Arg&)'
  3. 错误C2514:'UnaryConvolution':类没有构造函数

即使添加线int val = 3然后传递val也没有效果.(顺便说一句,项目被禁止使用Boost或任何第三方库.不要问,我尽量不这样做.)

Jam*_*lis 6

UnaryConvolution是一个类模板,而不是一个类.您需要指定用于实例化模板的模板参数.例如,

UnaryConvolution<
    function<bool(bool)>, 
    function<bool(int)>
> obj(bind2nd( equal_to<bool>(), true ), bind2nd( less<int>(), 5 ));
Run Code Online (Sandbox Code Playgroud)

(我已经使用过function,你可以从Boost,C++ TR1或C++ 0x中获取,代替实际的返回类型bind2nd,这不是那么简单.如果你没有访问某些实现的function,那么你需要弄清楚返回类型bind2nd)


sbi*_*sbi 5

正如第一条错误消息所示,您需要指定模板参数UnaryConvolution:

UnaryConvolution<SomeF, SomeG> obj(...);
Run Code Online (Sandbox Code Playgroud)

当然,拼出结果std::bind2nd并不是很有趣.便利功能可能会有所帮助:

template<typename F, typename G>
inline UnaryConvolution<F,G> MakeUnaryConvolution(const F &_f, const G &_g)
{return UnaryConvolution<F,G>(f,g);}
Run Code Online (Sandbox Code Playgroud)

但是现在你遇到了必须找到将结果绑定到的东西的问题:

??? obj = MakeUnaryConvolution( bind2nd(equal_to<bool>(),true)
                              , bind2nd(less<int>(),5) );
Run Code Online (Sandbox Code Playgroud)

C++ 1x让你逃脱auto obj = ....但是,VS2005还不支持.我看到两种可能性:

  1. 使该类型成为执行实际工作的函数的模板参数.

    template< typename F >   
    bool doUnaryConvolution_test(F f, int i)
    {
      return f(i);
    }
    bool unaryConvolution_test()
    {
      return doUnaryConvolution_test( 
         MakeUnaryConvolution( bind2nd(equal_to<bool>(),true)
                             , bind2nd(less<int>(),5) ) );
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用std::tr1::function(不确定VS2005可用)或boost::function.

    std::tr1::function<bool(int)> obj = MakeUnaryConvolution( 
                                           bind2nd(equal_to<bool>(),true), 
                                           bind2nd(less<int>(),5) );
    
    Run Code Online (Sandbox Code Playgroud)