STL:卷积两个unary_function参数

时间:2010-09-08 14:55:53

标签: 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;
};

单元测试我写过:

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 );
}

我得到的错误:

  1. 错误C2955:'UnaryConvolution':使用类模板需要模板参数列表
  2. 错误C3848:具有'UnaryConvolution'类型的表达式会丢失一些const-volatile限定符,以便调用'_Result UnaryConvolution :: operator()(const _Arg&amp;)'
  3. 错误C2514:'UnaryConvolution':类没有构造函数
  4. 即使添加第int val = 3行,然后传递val也无效。 (顺便说一句,项目被禁止使用Boost或任何第三方库。不要问,我尽量不这样做。)

3 个答案:

答案 0 :(得分:6)

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

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

(我使用了function,您可以从Boost,C ++ TR1或C ++ 0x中获取bind2nd,而不是function的实际返回类型。如果您无权访问bind2nd的某些实现,那么您需要找出{{1}}的返回类型

答案 1 :(得分:5)

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

UnaryConvolution<SomeF, SomeG> obj(...);

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

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

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

??? obj = MakeUnaryConvolution( bind2nd(equal_to<bool>(),true)
                              , bind2nd(less<int>(),5) );

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) ) );
    }
    
  2. 使用std::tr1::function(不确定VS2005可用)或boost::function

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

答案 2 :(得分:2)

UnaryConvolution是一个类模板,因此在使用它时需要提供模板参数。但是,在处理仿函数或函数指针时,提供参数可能很麻烦,这就是为什么我们经常通过创建辅助函数来依赖模板参数推导:

template <typename F, typename G>
UnaryConvolution<F, G> make_UnaryConvolution(const F & f, const G & g)
{
    return UnaryConvolution<F, G>(f, g);
}