C ++에 __CLASS__ 매크로가 있습니까?
함수 이름을 제공하는 매크로 __CLASS__와 유사한 클래스 이름을 제공하는 C ++에 매크로 가 있습니까?__FUNCTION__
가장 가까운 것은 호출하는 것입니다 typeid(your_class).name(). 그러나 이것은 컴파일러에 특정한 이름을 엉망으로 만듭니다.
수업 내에서 사용하려면 typeid(*this).name()
사용시 문제 는 정적 메서드 호출에 포인터 typeid(*this).name()가 없다는 것입니다 this. 매크로 __PRETTY_FUNCTION__는 메서드 호출뿐만 아니라 정적 함수의 클래스 이름을보고합니다. 그러나 이것은 gcc에서만 작동합니다.
다음은 매크로 스타일 인터페이스를 통해 정보를 추출하는 예입니다.
inline std::string methodName(const std::string& prettyFunction)
{
size_t colons = prettyFunction.find("::");
size_t begin = prettyFunction.substr(0,colons).rfind(" ") + 1;
size_t end = prettyFunction.rfind("(") - begin;
return prettyFunction.substr(begin,end) + "()";
}
#define __METHOD_NAME__ methodName(__PRETTY_FUNCTION__)
매크로 __METHOD_NAME__는 형식의 문자열을 <class>::<method>()반환하여 반환 유형, 수정 자 및 인수를 __PRETTY_FUNCTION__제공합니다.
클래스 이름 만 추출하는 경우 클래스가없는 상황을 트랩하려면주의해야합니다.
inline std::string className(const std::string& prettyFunction)
{
size_t colons = prettyFunction.find("::");
if (colons == std::string::npos)
return "::";
size_t begin = prettyFunction.substr(0,colons).rfind(" ") + 1;
size_t end = colons - begin;
return prettyFunction.substr(begin,end);
}
#define __CLASS_NAME__ className(__PRETTY_FUNCTION__)
아직. ( __class__어딘가에서 제안 되었다고 생각합니다 ). 에서 클래스 부분을 추출 할 수도 있습니다 __PRETTY_FUNCTION__.
나는 Scott Meyer의 "Effective Modern C ++"에서 배운 boost :: typeindex 를 제안 하고 싶습니다. 다음은 기본적인 예입니다.
예
#include <boost/type_index.hpp>
class foo_bar
{
int whatever;
};
namespace bti = boost::typeindex;
template <typename T>
void from_type(T t)
{
std::cout << "\tT = " << bti::type_id_with_cvr<T>().pretty_name() << "\n";
}
int main()
{
std::cout << "If you want to print a template type, that's easy.\n";
from_type(1.0);
std::cout << "To get it from an object instance, just use decltype:\n";
foo_bar fb;
std::cout << "\tfb's type is : "
<< bti::type_id_with_cvr<decltype(fb)>().pretty_name() << "\n";
}
"g ++ --std = c ++ 14"로 컴파일하면 다음이 생성됩니다.
산출
템플릿 유형을 인쇄하려면 간단합니다.
T = 이중
객체 인스턴스에서 가져 오려면 decltype을 사용하십시오.
fb의 유형 : foo_bar
나는 사용할 수 있을 때까지 __PRETTY_FUNCTION__네임 스페이스도 포함하지만 사용하면 충분 하다고 생각 합니다.namespace::classname::functionname__CLASS__
If your compiler happens to be g++ and you are asking for __CLASS__ because you want a way to get the current method name including the class, __PRETTY_FUNCTION__ should help (according to info gcc, section 5.43 Function Names as Strings).
If you're talking MS C++ (You should state, esp as __FUNCTION__ is a non-standard extension), there are __FUNCDNAME__ and __FUNCSIG__ symbols which you could parse
You can get the function name including class name. This can process C-type funcitons.
static std::string methodName(const std::string& prettyFunction)
{
size_t begin,end;
end = prettyFunction.find("(");
begin = prettyFunction.substr(0,end).rfind(" ") + 1;
end -= begin;
return prettyFunction.substr(begin,end) + "()";
}
My solution:
std::string getClassName(const char* fullFuncName)
{
std::string fullFuncNameStr(fullFuncName);
size_t pos = fullFuncNameStr.find_last_of("::");
if (pos == std::string::npos)
{
return "";
}
return fullFuncNameStr.substr(0, pos-1);
}
#define __CLASS__ getClassName(__FUNCTION__)
I works for Visual C++ 12.
Here's a solution based on the __FUNCTION__ macro and C++ templates:
template <class T>
class ClassName
{
public:
static std::string Get()
{
// Get function name, which is "ClassName<class T>::Get"
// The template parameter 'T' is the class name we're looking for
std::string name = __FUNCTION__;
// Remove "ClassName<class " ("<class " is 7 characters long)
size_t pos = name.find_first_of('<');
if (pos != std::string::npos)
name = name.substr(pos + 7);
// Remove ">::Get"
pos = name.find_last_of('>');
if (pos != std::string::npos)
name = name.substr(0, pos);
return name;
}
};
template <class T>
std::string GetClassName(const T* _this = NULL)
{
return ClassName<T>::Get();
}
Here's an example of how this could be used for a logger class
template <class T>
class Logger
{
public:
void Log(int value)
{
std::cout << GetClassName<T>() << ": " << value << std::endl;
std::cout << GetClassName(this) << ": " << value << std::endl;
}
};
class Example : protected Logger<Example>
{
public:
void Run()
{
Log(0);
}
}
The output of Example::Run will then be
Example: 0
Logger<Example>: 0
If you need something that will actually produce the class name at compile time, you can use C++11 to do this:
#define __CLASS__ std::remove_reference<decltype(classMacroImpl(this))>::type
template<class T> T& classMacroImpl(const T* t);
I recognize that this is not the same thing as __FUNCTION__ but I found this post while looking for an answer like this. :D
This works quite nicely if you are willing to pay the cost of a pointer.
class State
{
public:
State( const char* const stateName ) :mStateName( stateName ) {};
const char* const GetName( void ) { return mStateName; }
private:
const char * const mStateName;
};
class ClientStateConnected
: public State
{
public:
ClientStateConnected( void ) : State( __FUNCTION__ ) {};
};
Works with msvc and gcc too
#ifdef _MSC_VER
#define __class_func__ __FUNCTION__
#endif
#ifdef __GNUG__
#include <cxxabi.h>
#include <execinfo.h>
char *class_func(const char *c, const char *f)
{
int status;
static char buff[100];
char *demangled = abi::__cxa_demangle(c, NULL, NULL, &status);
snprintf(buff, sizeof(buff), "%s::%s", demangled, f);
free(demangled);
return buff;
}
#define __class_func__ class_func(typeid(*this).name(), __func__)
#endif
Following method (based on methodName() above) can also handle input like "int main(int argc, char** argv)":
string getMethodName(const string& prettyFunction)
{
size_t end = prettyFunction.find("(") - 1;
size_t begin = prettyFunction.substr(0, end).rfind(" ") + 1;
return prettyFunction.substr(begin, end - begin + 1) + "()";
}
참고URL : https://stackoverflow.com/questions/1666802/is-there-a-class-macro-in-c
'developer tip' 카테고리의 다른 글
| 스택 변수가 GCC __attribute __ ((aligned (x)))에 의해 정렬됩니까? (0) | 2020.09.14 |
|---|---|
| Java에서 시간 초과가있는 일부 차단 메서드를 어떻게 호출합니까? (0) | 2020.09.14 |
| MySQL을 다시 시작하지 않고 MySQL의 느린 쿼리 로그를 활성화하려면 어떻게해야합니까? (0) | 2020.09.14 |
| HTTPS 페이지에서 HTTP 콘텐츠 다루기 (0) | 2020.09.14 |
| / bin / sh : pushd : 찾을 수 없음 (0) | 2020.09.14 |