我要求一个模板技巧来检测一个类是否具有给定签名的特定成员函数.
问题类似于这里引用的问题 http://www.gotw.ca/gotw/071.htm 但不一样:在Sutter的书中,他回答了C类必须提供成员函数的问题.一个特定的签名,否则程序将无法编译.在我的问题中,我需要做一些事情,如果一个类有这个功能,否则做"其他".
boost :: serialization面临类似的问题,但我不喜欢他们采用的解决方案:模板函数默认调用具有特定签名的自由函数(您必须定义),除非您定义特定的成员函数(在他们的情况下"序列化",它采用给定类型的2个参数)与特定签名,否则将发生编译错误.那就是实现侵入式和非侵入式序列化.
我不喜欢这个解决方案有两个原因:
我需要为没有该成员函数的类定义自定义行为,并且我的实体位于不同的名称空间内(我不想覆盖在一个名称空间中定义的全局函数,而我在另一个名称空间中)
你能给我一个解决这个难题的提示吗?
是否有可能写出一个类型特征,比如说is_callable<T>一个对象是否已operator()定义?如果调用运算符的参数事先已知,则很容易,但在一般情况下则不行.当且仅当至少有一个重载调用运算符被定义时,我希望特征返回true.
这个问题是相关的,并且有一个很好的答案,但它不适用于所有类型(仅限于 - 可int转换类型).此外,std::is_function工作,但只适用于正确的C++函数,而不是函子.我正在寻找更通用的解决方案.
我有一个模板化的错误报告函数,因为它可以报告许多不同消息类别的错误:
template <typename MSG>
void reportErr(const MSG& msg)
{
std::cout << "ERROR: " << msg.error << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
然而,某些类型的消息具有可以报告的更详细的错误或其他专门的错误报告,例如
template<>
void reportErr(const SpecificMsg& msg)
{
std::cout << "ERROR: " << msg.error;
std::cout << ", details: " << msg.details << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
由于有很多类型SpecificMsg,例如 ,我不想为每种类型创建单独的模板专业化。是否可以为具有成员变量的任何类型创建通用特化/部分特化.details?
如果可能的话,我想要一种方法来一般地执行此操作(因此,如果有.details,则一种专业化,如果有.other_info,则另一种专业化,等等)。
编辑:这是明确询问功能。我见过一些代码可以执行类似的操作来专门化模板类,但我从未遇到过可以对非成员函数执行我想要的操作的代码。我怀疑将用于类的方法转换为用于函数的方法并不难,但我一直无法弄清楚如何做到这一点。
编辑 2:我的 gcc 版本(4.6.3)似乎不支持完整的 C++11 标准,因此void_t“重复”问题中提到的选项对我不起作用。我的编译器抱怨“‘类型’之前预期有嵌套名称说明符”等,甚至不让我定义 void_t。因此,我从问题中删除了 C++11 标签。