2012-01-01 139 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; 
} 

編譯器錯誤:錯誤:無效的參數類型「無效」

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

你能構建一個** **最小的測試案例? – 2012-01-01 16:53:51

+0

我在主函數 – q0987 2012-01-01 16:55:54

+0

中給出了我的意思是一個仍然存在問題的精簡代碼片段(請參閱http://sscce.org)。我敢打賭,上述代碼的90%與您面臨的問題完全無關。 – 2012-01-01 16:57:32

回答

2

這是一個與你的模板專業化的問題。變化:

class<void, void> invoker_base { 

到:

class invoker_base<void, void> { 
+0

你說得對。謝謝 – q0987 2012-01-01 16:59:23