2012-08-02 36 views
0

我有一個Singleton類只有一個我的MPIProxy類的單個實例(否則會導致許多結構)。有沒有辦法typedef一個靜態函數

要創建單一MPIProxy類,我有以下的typedef:

typedef Singleton<MPIProxy_> MPIProxySingleton; 

不過來訪問我需要下面的代碼實例:

int myrank = MPIProxySingleton::instance().getRank(); 

我寧願讓客戶寫而不是MPIProxySingleton::instance().xy()只需MPIProxy.xy()。其中.xy是MPIProxy_類的函數。這樣上面的代碼看起來像:

int myrank = MPIProxy.getRank(); 

我已經試過follwing:

typedef MPIProxySingleton::instance() MPIProxy; 

然而,這導致編譯錯誤:

/Users/david/Desktop/GSOC/miind/miind/./libs/MPILib/include/utilities/MPIProxy.hpp:158:31: error: C++ requires a type specifier for all declarations 
typedef Singleton<MPIProxy_>::instance() MPIProxy; 
~~~~~~~      ^
/Users/david/Desktop/GSOC/miind/miind/./libs/MPILib/include/utilities/MPIProxy.hpp:158:41: error: expected ';' after top level declarator 
typedef Singleton<MPIProxy_>::instance() MPIProxy; 

這是我單身的代碼等級:

/** Singleton holder template class. 
* Template class to create singletons. A singleton instance of class 
* MyType is created and accessed using 
* \code 
* typedef Singleton<MyType> MySingletonType; 
* MyType& myRef = MySingletonType::instance() 
* // ... do something ... 
* \endcode 
*/ 
template<class T> 
class Singleton 
{ 
public: 
    // disallow creation, copying and assignment 

    /** Deleted constructor to disallow explicit construction. 
    * Is not defined. 
    */ 
    Singleton()=delete; 

    /** Deleted copy constructor to disallow explicit copying. 
    * Is not defined. 
    * @param S A singleton object. 
    */ 
    Singleton(const Singleton& S)=delete; 

    /** Deleted assignment operator to disallow explicit assignment. 
    * @param S A singleton object. 
    * @return The current singleton. 
    */ 
    Singleton& operator=(const Singleton& S)=delete; 

    /** Return a reference to the only instance of \c Singleton<T>. 
    * @return A reference to the instance of the object. 
    */ 
    static T& instance(); 

    /** Destructor. 
    */ 
    ~Singleton(); 

private: 


    /** Create method. Creates the singleton instance (a Meyers singleton, ie. 
    * a function static object) upon the first call to \c instance(). 
    */ 
    static void create(); 

    /** Pointer to the instance. 
    */ 
    static T* pInstance_; 

    /** Status of the singleton. True if the singleton was destroyed. 
    */ 
    static bool destroyed_; 

}; 

/** Returns the unique instance of class T. If it was already 
* deleted an exception is thrown. If the class T was never used 
* before a new instance is generated. 
* 
* @return Unique instance of class T 
*/ 
template<class T> T& Singleton<T>::instance() 
{ 
    if (!pInstance_) { 
     if (destroyed_) { 
      // dead reference 
      throw Exception("The instance was already destroyed"); 
     } else { 
      // initial creation 
      create(); 
     } 
    } 
    return *pInstance_; 
} 

template<class T> Singleton<T>::~Singleton() 
{ 
    pInstance_ = 0; 
    destroyed_ = true; 
} 

template<class T> void Singleton<T>::create() 
{ 
    static T theInstance; 
    pInstance_ = &theInstance; 
} 

template<class T> T* Singleton<T>::pInstance_ = 0; 
template<class T> bool Singleton<T>::destroyed_ = false; 

這裏我MPIProxy_類的頭

class MPIProxy_ { 
public: 
    /** 
    * destructor 
    */ 
    virtual ~MPIProxy_(); 

    /** 
    * wrapper method to return the process id, if mpi is disabled it returns 0 
    * @return the world rank of a process 
    */ 
    int getRank() const; 

    /** 
    * wrapper method to return the size, if MPI is disabled it returns 1 
    * @return 
    */ 
    int getSize() const; 

    /** 
    * wrapper for mpi barrier 
    */ 
    void barrier(); 

    /** 
    * waits until all request stored in the vector _mpiStatus are finished 
    */ 
    void waitAll(); 

    /** 
    * Broadcast the value from root 
    * @param value The value to be broadcast 
    * @param root The root process 
    */ 
    template<typename T> 
    void broadcast(T& value, int root); 

    /** 
    * asynchronous receive operation the mpi status is stored in _mpiStatus 
    * @param source The source of the message 
    * @param tag The tag of the message 
    * @param value The value received 
    */ 
    template<typename T> 
    void irecv(int source, int tag, T& value) const; 

    /** 
    * asynchronous send operation the mpi status is stored in _mpiStatus 
    * @param dest The destination of the message 
    * @param tag The tag of the message 
    * @param value The value sended 
    */ 
    template<typename T> 
    void isend(int dest, int tag, const T& value) const; 


private: 
    /** 
    * Declare the Singleton class a friend to allow construction of the MPIProxy_ class 
    */ 
    friend class Singleton<MPIProxy_>; 
    /** 
    * constructor sets the MPI rank and size 
    */ 
    MPIProxy_(); 

#ifdef ENABLE_MPI 
    /** 
    * stores the mpi statuses 
    */ 
    static std::vector<boost::mpi::request> _mpiStatus; 
#endif 

    /** 
    * storage of the rank to avoid function calls 
    */ 
    static int _rank; 

    /** 
    * storage of the size to avoid function calls 
    */ 
    static int _size; 
}; 

template<typename T> 
void MPIProxy_::broadcast(T& value, int root) { 
#ifdef ENABLE_MPI 
    mpi::communicator world; 
    boost::mpi::broadcast(world, value, root); 
#endif 
} 

template<typename T> 
void MPIProxy_::irecv(int source, int tag, T& value) const { 
#ifdef ENABLE_MPI 
    mpi::communicator world; 
    _mpiStatus.push_back(world.irecv(source, tag, value)); 
#else 
    MPILib::utilities::Exception("MPI Code called from serial code in irecv"); 
#endif 
} 

template<typename T> 
void MPIProxy_::isend(int dest, int tag, const T& value) const { 
#ifdef ENABLE_MPI 
    mpi::communicator world; 
    _mpiStatus.push_back(world.isend(dest, tag, value)); 
#else 
    MPILib::utilities::Exception("MPI Code called from serial code in isend"); 
#endif 
} 

typedef Singleton<MPIProxy_> MPIProxySingleton; 
//typedef MPIProxySingleton::instance() MPIProxy; 
+0

這一切都搞砸了。類型是靜態的。您正在嘗試執行函數調用,然後創建返回值,這是一個實例,一種類型! – 2012-08-02 07:21:06

回答

3

包裝函數總是在這種情況下,一個很好的選擇:

MPIProxy_ & MPIProxy() 
{ 
    return MPIProxySingleton::instance(); 
} 

然後用它作爲:

MPIProxy().xy(); 
+0

你需要一個回報和一個; – 2012-08-02 07:24:29

+0

謝謝,這是我正在尋找的:) – tune2fs 2012-08-02 07:26:34

0

做一個參考吧:

MPIProxy_& MPIProxy = MPIProxySingleton::instance(); 
+2

這不是一個參考,而是一個'operator&='和一個語法錯誤。 – iammilind 2012-08-02 07:20:31

+0

@ iammilind謝謝,修正。 – 2012-08-02 07:21:16

+0

這就是我目前使用它的方式(請參閱singleton類的評論)。然而,我需要這個類在我的代碼中的很多位置,然後只需要調用MPIProxy_的一個函數。因此,如果可能的話,我也想避免使用此代碼語句。 – tune2fs 2012-08-02 07:23:30

1

我只是想p憎恨完成同樣事情的一個稍微不同的方式。由於Singleton應該是無狀態的,因此實際上不允許Singleton被實例化或複製或分配或銷燬。它只是模板參數的單個靜態實例的包裝器。鑑於這種情況,你可以定義你的Singleton這樣:

template <typename T> 
class Singleton { 
public: 
    static T & instance() { 
     static T instance_; 
     return instance_; 
    } 
    T * operator ->() const { return &instance(); } 
}; 

所以,對於對象,你打算做一個Singleton

class Foo_ { 
    friend class Singleton<Foo_>; 
    Foo_() {} 
public: 
    void bar() { std::cout << __PRETTY_FUNCTION__ << std::endl; } 
}; 

typedef Singleton<Foo_> Foo; 

然後,你可以使用它像這樣:

Foo()->bar(); 
相關問題