【发布时间】:2016-05-15 18:53:13
【问题描述】:
从this question, which asks about SFINAE 开始,它给出了以下示例:
template<class T>
std::string optionalToString(T* obj)
{
if (FUNCTION_EXISTS(T->toString))
return obj->toString();
else
return "toString not defined";
}
但是,如果一个对象没有例如 toString() 函数,而不是这种情况返回“toString not defined”,即使我们可以检测到该函数是否存在,编译器仍然会抛出在突出显示指针 toString 调用之前,对象没有名为“toString”的成员的错误。
我希望能够对来自具有不同命名约定的 C++ 库的对象执行相同的操作,例如:
if(R_Contains_SetPosition<TemplateObject>::Value)
{
TemplateObject->SetPosition(X,Y);
}
else if(R_Contains_setPosition<TemplateObject>::Value)
{
TemplateObject->setPosition(X,Y); //TemplateObject doesn't have a setPosition defined!
}
代码已经可以执行的操作,但是编译器会在调用对象未定义的函数的任何语句上引发错误。
有没有办法让编译器接受能够调用成员函数(在这种情况下无论如何都不会运行)的代码(通过重写或修改编译器标志,最好是前者) ),即使编译器知道所说的成员函数不存在?
澄清:
这不是问如何检测函数是否存在。我已经有这个能力了。,它在问我如何编写代码来引用一个对象不一定有的函数,而编译器不会抱怨它?
系统是 C++03,因此类似 C++14 的实验性解决方案在此无效。
【问题讨论】:
-
没有。函数中的所有代码都是实例化的,并且必须对呈现的类型有效。您必须使用 sfinae 和专业化来制作始终适用于所有给定类型的函数。 boost::hana 的代码使这更容易,看起来更像你的建议,但它是 sfinae 的语法糖。
-
呃...这不是您链接到自己的问题的完整副本吗?在发布此问题之前,您是否阅读了那里的答案?我很想关闭它,但如果我遗漏了什么,我会给你机会回复。
-
因为执行 ->toString,即使使用建议的函数检查器,也会引发成员函数不存在的错误。我不是在问“我如何检查一个函数是否存在”,我是在问“我如何欺骗编译器不让我知道一个函数不存在”。
-
@c1646091 那里的答案已经涵盖了这一点。 Johannes Schaub 的回答很好地涵盖了这一点。
-
Johannes Schaub 对分析的回答在很大程度上是不完整的(缺少尖括号,没有返回类型,也没有关于如何调用他的 enable_if 的示例——这似乎违反了保留关键字,因此必须重命名)。虽然它是伪代码,但我不知道如何确保它正常工作。
标签: c++ sfinae c++03 member-functions