gpt4 book ai didi

c++ - 用模板实现替换预处理器 #ifdef block

转载 作者:行者123 更新时间:2023-11-30 03:38:41 25 4
gpt4 key购买 nike

我有一堆代码,其中混杂着预处理器 block ,例如 #ifdef FEATURE_A#ifdef _MSC_VER 等等。

我想重构一些代码,以便用模板实现替换一些预处理器 block 。

编辑:任务不是移除所有预处理器 block ,而是移除其中的一些,以摆脱困惑。

我不想用 foobar 的例子让你厌烦,所以这里有一个来自现实世界的例子(不是我的代码):

template <typename T>
std::string demangle()
{
#ifdef __GNUC__
size_t sz;
int status;
char* ptr = abi::__cxa_demangle(typeid(T).name(), 0, &sz, &status);
std::string name(ptr ? ptr : "", ptr ? strlen(ptr) : 0);
if(ptr){ free(ptr); }
std::string::size_type pos = name.rfind("::");
if(pos != std::string::npos)
{
name = name.substr(pos + 2);
}
#elif _MSC_VER
std::string name(typeid(T).name());
static const std::string struct_prefix("struct ");
static const std::string class_prefix("class ");
static const std::string ptr_postfix(" *");

std::string::size_type
at = name.find(struct_prefix);
if(at != std::string::npos) { name.erase(at, struct_prefix.size()); }
at = name.find(class_prefix);
if(at != std::string::npos) { name.erase(at, class_prefix.size()); }
at = name.find(ptr_postfix);
if(at != std::string::npos) { name.erase(at, ptr_postfix.size()); }
#else
std::string name(typeid(T).name());
#endif
return name;
}

问题 1:如何将其转换为等效的模板实现?

问题 2:为什么值得付出努力,或者为什么不值得?

最佳答案

这是不可能的。 C++ 模板使用两阶段查找 (Two phase name lookup for C++ templates - Why?),因此在函数模板中使用的任何不依赖于模板参数的名称必须在声明时可用。

您的 GCC 实现使用名称 abi::__cxa_demangle,因此任何不提供该名称的实现都应该拒绝您的代码(有些可能不会,但只是因为它们没有实现两阶段正确查找:What exactly is "broken" with Microsoft Visual C++'s two-phase template instantiation? )。

解决此问题的唯一方法是在预处理器 #ifdef block 中包含 abi::__cxa_demangle 的使用,这实际上意味着无论如何都要使用您的原始实现。

关于c++ - 用模板实现替换预处理器 #ifdef block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39409295/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com