2012-01-01 6 views
1
#include <iostream> 
#include <vector> 
#include <string> 
#include <ostream> 
#include <algorithm> 

#include <boost/function.hpp> 
#include <boost/bind.hpp> 
#include <boost/cast.hpp> 

using namespace std; 

class tape_recorder { 
public: 
    void play() { 
    std::cout << "Since my baby left me...\n"; 
    } 

}; 

template <typename R, typename Arg> 
class invoker_base { 
public: 
    virtual R operator()(Arg arg)=0; 
}; 
template <> 
class<void, void> invoker_base { 
public: 
    virtual void operator()(void)=0; 
}; 


template <typename R, typename Arg, typename T> 
class member_ptr_invoker : public invoker_base<R,Arg> { 
    R (T::*func_)(Arg); 
    T* t_; 
public: 
    member_ptr_invoker(R (T::*func)(Arg),T* t) 
    :func_(func),t_(t) {} 

    R operator()(Arg arg) { 
    return (t_->*func_)(arg); 
    } 
}; 
template <typename T> 
class member_ptr_invoker<void, void, T> : public invoker_base<void,void> { 
    void (T::*func_)(void); 
    T* t_; 
public: 
    member_ptr_invoker(void (T::*func)(void),T* t) 
    :func_(func),t_(t) {} 

    void operator()(void arg) { 
    return (t_->*func_)(arg); 
    } 
}; 

int main(void) 
{ 
    tape_recorder tr; 

    // member_ptr_invoker 
    member_ptr_invoker<void, void, tape_recorder> mpi(&tape_recorder::play, &tr); 
    //mpi(); 

    return 0; 
} 

Compiler ошибки:ошибка: неверный тип параметра «пустота»

g++ -o p337 p337.cpp -Wall 
p337.cpp:47:6: error: expected identifier before ‘<’ token 
p337.cpp:47:6: error: expected unqualified-id before ‘<’ token 
p337.cpp: In instantiation of ‘invoker_base<void, void>’: 
p337.cpp:66:74: instantiated from here 
p337.cpp:44:13: error: invalid parameter type ‘void’ 
p337.cpp:44:13: error: in declaration ‘virtual R invoker_base<R, Arg>::operator()(Arg)’ 
p337.cpp:73:24: error: ‘arg’ has incomplete type 
p337.cpp:73:27: error: invalid use of ‘void’ 

Вопрос> Как исправить ошибки компиляции?

Спасибо

// ============ Fixed version ======================= 
#include <iostream> 
#include <vector> 
#include <string> 
#include <ostream> 
#include <algorithm> 

#include <boost/function.hpp> 
#include <boost/bind.hpp> 
#include <boost/cast.hpp> 

using namespace std; 

class tape_recorder { 
public: 
    void play() { 
    std::cout << "Since my baby left me...\n"; 
    } 

    void stop() { 
    std::cout << "OK, taking a break\n"; 
    } 

    void forward() { 
    std::cout << "whizzz\n"; 
    } 

    void rewind() { 
    std::cout << "zzzihw\n"; 
    } 

    void record(const std::string& sound) { 
    std::cout << "Recorded: " << sound << '\n'; 
    } 
}; 

int roundToInt(double d) 
{ 
    return boost::numeric_cast<int> (d + 0.5); 
} 

template <typename R, typename Arg> 
class invoker_base { 
public: 
    virtual R operator()(Arg arg)=0; 
}; 
template <> 
class invoker_base<void, void> { 
public: 
    virtual void operator()(void)=0; 
}; 

template <typename R, typename Arg, typename T> 
class member_ptr_invoker : public invoker_base<R,Arg> { 
    R (T::*func_)(Arg); 
    T* t_; 
public: 
    member_ptr_invoker(R (T::*func)(Arg),T* t) 
    :func_(func),t_(t) {} 

    R operator()(Arg arg) { 
    return (t_->*func_)(arg); 
    } 
}; 
template <typename T> 
class member_ptr_invoker<void, void, T> : public invoker_base<void,void> { 
    void (T::*func_)(void); 
    T* t_; 
public: 
    member_ptr_invoker(void (T::*func)(void),T* t) 
    :func_(func),t_(t) {} 

    void operator()() { 
    return (t_->*func_)(); 
    } 
}; 

int main(void) 
{ 
    tape_recorder tr; 

    // member_ptr_invoker 
    member_ptr_invoker<void, void, tape_recorder> mpi(&tape_recorder::play, &tr); 
    mpi(); 

    return 0; 
} 
+0

могли бы вы построить ** ** минимальный тест-случай? –

+0

Я дал в основной функции – q0987

+0

Я имею в виду фрагмент сокращенного кода, который все еще обнаруживает проблему (см. Http://sscce.org). Готов поспорить, что 90% вышеуказанного кода совершенно не имеют отношения к проблеме, с которой вы столкнулись. –

ответ

2

Это проблема с вашей специализации шаблона. Изменение:

class<void, void> invoker_base { 

к:

class invoker_base<void, void> { 
+0

Вы правы. спасибо – q0987

Смежные вопросы