gpt4 book ai didi

c++ - 如果参数有成员变量,则特化函数

转载 作者:太空狗 更新时间:2023-10-29 20:09:01 25 4
gpt4 key购买 nike

我有一个模板化的错误报告功能,因为它可以报告许多不同消息类别的错误:

template <typename MSG>
void reportErr(const MSG& msg)
{
std::cout << "ERROR: " << msg.error << std::endl;
}

但是,某些类型的消息具有更详细的错误,可以报告或其他专门的错误报告,例如

template<>
void reportErr(const SpecificMsg& msg)
{
std::cout << "ERROR: " << msg.error;
std::cout << ", details: " << msg.details << std::endl;
}

由于有许多类型,如 SpecificMsg,我不想为每种类型创建单独的模板特化。是否可以为具有 .details 成员变量的任何类型创建通用特化/部分特化?

如果可能的话,我想要一种通用的方法(所以如果它有 .details 就一个专门化,如果它有 .other_info 就不同,等等).

编辑:这是明确询问功能。我见过执行类似操作以专门化模板 的代码,但我从未遇到过能为非成员函数执行我想要的操作的代码。我怀疑将用于类的方法转换为用于函数并不难,但我一直无法弄清楚如何去做。

编辑 2:我的 gcc (4.6.3) 版本似乎不支持完整的 C++11 标准,因此 void_t “重复”问题中提到的选项对我不起作用。我的编译器提示“'类型'之前需要嵌套名称说明符”等等,甚至不让我定义 void_t。因此,我从我的问题中删除了 C++11 标签。

最佳答案

为此我会使用 SFINAE。首先,让我们定义两个函数,它们返回错误消息的字符串:

namespace detail
{
// for messages with "details" member:
template<typename MsgType>
std::string makeMsgString(const MsgType& msg, decltype(MsgType::details)*)
{
return "Error: " + msg.error + ", details: " + msg.details;
}

// for messages without "details" member:
template<typename MsgType>
std::string makeMsgString(const MsgType& msg, ...)
{
return "Error: " + msg.error + ", no details";
}
}

现在,这些函数可以这样使用:

struct NonSpecificMsg { std::string error; };
struct SpecificMsg { std::string error, details; };

template<typename MsgType>
void reportErr(const MsgType& msg)
{
std::cout << detail::makeMsgString(msg, nullptr) << "\n";
}

int main()
{
reportErr(NonSpecificMsg { "some error" }); // 1
reportErr(SpecificMsg { "some other error", "some details" }); // 2
return 0;
}

这里发生了什么?

调用 1): NonSpecificMsg 没有 details 成员,因此第一个重载不存在。由于 MsgType::details 不存在,因此 decltype(MsgType::details)* 不是有效类型。 SFINAE 导致此定义被忽略,而不是在编译期间抛出错误。只有重载 2),它不访问 details 成员。

Call 2): SpecificMsgdetails,因此编译器会考虑这两个重载。但是,可变函数重载(第二个)的优先级始终低于任何其他匹配重载,因此选择第一个。

编辑:这是一个 C++11 解决方案。不幸的是,decltype 是在 GCC 4.8 中引入的。

编辑 2: 事实证明,decltype 可以 与 GCC 4.6 一起使用(它是在 4.3 版中引入的)。版本 4.8.1 改变了它的语义,但在 OP 的情况下,以前的版本仍然有效 - 参见 GCC's C++ status page

关于c++ - 如果参数有成员变量,则特化函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50295630/

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