首页 > 解决方案 > 使用宏#获取函数指针的函数名不起作用

问题描述

我有一个这样定义的助手类:

数据卫士.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"

数据卫士.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 宏让我失望?

标签: c++templatesmacrosfunction-pointers

解决方案


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

您可以在外部执行以下操作:

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));

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


推荐阅读