STL: свертывание двух аргументов unary_function - PullRequest
0 голосов
/ 08 сентября 2010

Работаю в Windows с VS2005 и пытаюсь понять сообщения об ошибках, которые я получаю.Если этот вопрос уже задавался, извините.Я не смог его найти.

Класс, который я тестирую:

#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 &)'
  3. ошибка C2514: 'UnaryConvolution': у класса нет конструкторов

, даже с добавлением строки int val = 3 и затемпрохождение val не имеет никакого эффекта.(Кстати, в проекте запрещено использовать Boost или любую стороннюю библиотеку. Не спрашивайте, я стараюсь этого не делать).

Ответы [ 3 ]

6 голосов
/ 08 сентября 2010

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)

5 голосов
/ 08 сентября 2010

Как и в первом сообщении об ошибке, вам необходимо указать аргументы шаблона для 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 голосов
/ 08 сентября 2010

UnaryConvolution - это шаблон класса, поэтому при его использовании необходимо указать аргументы шаблона.Однако при работе с функторами или указателями на функции предоставление аргументов может быть громоздким, поэтому мы часто полагаемся на вывод аргументов шаблона, делая вспомогательную функцию:

template <typename F, typename G>
UnaryConvolution<F, G> make_UnaryConvolution(const F & f, const G & g)
{
    return UnaryConvolution<F, G>(f, g);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...