使用宏#获取函数指针的函数名称

时间:2018-11-07 16:46:17

标签: c++ templates macros function-pointers

我有一个这样定义的帮助程序类:

DataGuard.h

template<typename T, typename D>
class DataGuard {
public:
  typedef MY_STATUS( *FunctionType )( const T*, D* );

private:
  bool               _isSuccess;
  D&                 _data;
  const FunctionType _function;

public:
  explicit DataGuard( D& data, FunctionType& function, const T* ptr );
  ~DataGuard();
  bool isSuccess() const;
};
#define DATAGUARD( Type ) const DataGuard<Type, Type##Data>

#include "DataGuard.inl"

DataGuard.inl

#define GET_FUNCTION_NAME( functionName ) #functionName

template<typename T, typename D>
DataGuard<T,D>::DataGuard( D& data, FunctionType& function, const T* ptr ) :
  _data( data ),
  _function( function )
{
  auto iReturn = function( ptr, &data );
  _isSuccess = iReturn == MY_SUCCESS;
  if( !_isSuccess ) {
    Utility::logErrorMessage( GET_FUNCTION_NAME( _function ), iReturn );  
  }
}

template<typename T, typename D>
DataGuard<T,D>::~DataGuard() {
  if( _isSuccess ) {
    _function( NULL, &_data );
  }
}

template<typename T, typename D>
bool DataGuard<T,D>::isSuccess() const {
  return _isSuccess;
}

该帮助器类的调用方式如下:

DATAGUARD( MyObject ) guard( data, MyObjectGet, ptr );

问题是,如果DataGuard构造函数中有错误,我打印的错误消息将显示 _function 而不是所需的 MyObjectGet 函数名称。

有什么想法为什么GET_FUNCTION_NAME宏使我失败?

1 个答案:

答案 0 :(得分:1)

您不能从函数内部做到这一点。

您可以在外部进行操作:

DATAGUARD( MyObject ) guard( data, MyObjectGet, ptr );

我会改变这一点:

#define  DG(data, func, ptr)     data, func, ptr, #func

// usage is now:
DATAGUARD( MyObject )  guard(DG(guard, data, MyObjectGet, ptr));

您会注意到,我们将函数指针和函数指针的名称作为加引号的字符串作为最后一个参数进行传递。您可以将此字符串用作错误消息的一部分。