代码之家  ›  专栏  ›  技术社区  ›  wheaties

STL:卷积两个一元函数参数

  •  0
  • wheaties  · 技术社区  · 14 年前

    我测试的班级:

    #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. 错误C3848:类型为“unarycolution”的表达式将丢失一些常量volatile限定符,以便调用“\u Result unarycolution::operator()(const\u Arg&)”
    2. 错误C2514:“unarycolution”:类没有构造函数

    甚至添加行 int val = 3 然后经过 val 没有效果。(顺便说一句,项目禁止使用Boost或任何第三方库。别问,我尽量不问。)

    3 回复  |  直到 14 年前
        1
  •  6
  •   James McNellis    14 年前

    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 ,这并不是那么简单。如果您无法访问 功能 ,那么您需要找出 绑定2 )

        2
  •  5
  •   sbi    14 年前

    正如第一条错误消息所说,您需要指定 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) );
      
        3
  •  2
  •   Luc Touraille    14 年前

    UnaryConvolution

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