2012-08-02 64 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(); 
相关问题