0
是否可以在编译时/运行时获取变量名称或枚举值名称?特别是,namespace::
/class::
/struct::
/union::
-qualified(具有可调节深度,如同UNIX补丁程序不灵活-p
/--strip=
选项)。在GCC 4.8.1我可以这样写:编译时间/运行时变量名称/枚举值名称信息
#include <iostream>
#include <ostream>
#include <cstdlib>
enum class mnemocode
{
fwait,
finit,
fninit,
fstsw,
fnstsw,
// ...
sahf,
ret,
prologue,
epilogue,
sp_inc,
sp_dec,
call
};
inline /* till C++14 cannot be constexpr */
auto mnemocode_name(mnemocode _mnemocode)
{
switch (_mnemocode) {
case mnemocode::fwait : return "fwait";
case mnemocode::finit : return "finit";
case mnemocode::fninit : return "fninit";
case mnemocode::fstsw : return "fstsw";
case mnemocode::fnstsw : return "fnstsw";
// ...
case mnemocode::sahf : return "sahf";
case mnemocode::ret : return "ret";
case mnemocode::prologue : return "prologue";
case mnemocode::epilogue : return "epilogue";
case mnemocode::sp_inc : return "sp_inc";
case mnemocode::sp_dec : return "sp_dec";
case mnemocode::call : return "call";
default : return "[unknown instruction]";
}
}
inline
std::ostream & operator << (std::ostream & out, mnemocode _mnemocode)
{
return out << mnemocode_name(_mnemocode);
}
int main()
{
std::cout << mnemocode::fwait << std::endl; // fwait
return EXIT_SUCCESS;
}
但我希望能够做到以下几点:有些虚constexpr abi::__get_value_info(symbol)
类的手段
template< typename M, typename = typename std::enable_if< std::is_same< mnemocode, typename std::remove_reference< typename std::remove_cv<M>::type >::type >::value >
inline constexpr
auto mnemocode_name(M && _mnemocode)
{
constexpr auto const depth = std::numeric_limits<std::size_t>::max(); // remove all qualifiers before last operator ::
return abi::__get_value_info(_mnemocode).name(depth); // compile time if M is constexpr
}
。
GCC让我写:
#include <iostream>
#include <string>
#include <type_traits>
#include <cxxabi.h>
#include <cstdlib>
template< typename T >
/* cannot be constexpr :(*/
const char * this_type()
{
return __PRETTY_FUNCTION__;
}
template< typename T >
std::string theirs_type()
{
int status = 0;
auto realname_(abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status));
switch (status) {
case -1: return "Could not allocate memory";
case -2: return "Invalid name under the C++ ABI mangling rules";
case -3: return "Invalid argument to demangle";
}
std::string os(realname_);
std::free(realname_);
if (std::is_volatile<T>::value) {
os = "volatile " + os;
}
if (std::is_const<T>::value) {
os += " const";
}
if (std::is_rvalue_reference<T>::value) {
os += " &&";
} else if (std::is_lvalue_reference<T>::value) {
os += " &";
}
return os;
}
int main()
{
std::cout << this_type< decltype(static_cast< double const >(double())) >() << std::endl; // const char* this_type() [with T = double]
std::cout << theirs_type< double const && >() << std::endl; // double &&
return EXIT_SUCCESS;
}
但这仅仅是对类型名称和编译时扣除太远。
我想这就是我所想到的,需要几乎嵌入到我的可执行调试器以及调试信息部分的可用性。但我仍然认为,这根本不可能。
你知道任何的替代品在这里×宏?我即将使用x宏进行制作,而我真的很害怕我必须回到这个位置。所有这些宏是邪恶的帖子吓唬我这么多! – NicoBerrogorry
我在生产代码中使用过这几次 - 它从来都不是问题。维护起来要容易得多。您不会得到冗长的嵌套开关语句,编译器会告诉您添加新枚举时缺少的内容。只要尝试一个noddy程序来检查机制。如果宏是邪恶的,他们就不会把它们放在语言中。 – cup
是的,我做了一些半复杂的样本和“实验室”代码,以确保它们正确,至少正确。是的,我猜如果他们在那里这是有原因的。为每个枚举器维护枚举和名称映射只是更短,更容易理解,我评论了所有接近矫枉过正的事情......但是,我的胆量告诉我这个设计存在问题,那不是预期的用于枚举。我应该写一个新问题吗? – NicoBerrogorry