是否可以编写一个模板来改变行为,具体取决于是否在类上定义了某个成员函数?
这是我想写的一个简单例子:
template<class T>
std::string optionalToString(T* obj)
{
if (FUNCTION_EXISTS(T->toString))
return obj->toString();
else
return "toString not defined";
}
Run Code Online (Sandbox Code Playgroud)
所以,如果class T已经toString()确定的话,就使用它; 否则,它没有.我不知道怎么做的神奇部分是"FUNCTION_EXISTS"部分.
最近我注意到,当在类中时,成员函数完全使用相同名称的阴影函数.完全我的意思是,每个具有相同名称的自由函数根本不考虑重载解析.我能理解为什么用这样的事情来完成它:
void f();
struct S
{
void f();
void g()
{
f(); // calls S::f instead of ::f
}
};
Run Code Online (Sandbox Code Playgroud)
在函数具有相同签名的情况下,其唯一自然的变量作用域以相同的方式工作.但是为什么要禁止自由函数具有不同签名的无意义调用:
void f();
struct S
{
void f(int x);
void g()
{
f(); // fails to compile attempting to call S::f, which has wrong signature
}
};
Run Code Online (Sandbox Code Playgroud)
我不是问如何从类中调用一个带阴影的自由函数.我想知道的是这种设计背后的基本原理.
如此处所述,C++11 样式 SFINAE 和模板实例化类成员函数上的函数可见性掩盖了自由函数。使用完全限定名称通常有效,但是我很难使用其他内嵌声明的类的友元函数。考虑以下示例:
namespace N {
struct C {
friend int f(const C& c) {
return 1;
}
friend int g(const C& c) {
return 2;
}
};
struct D {
void f() {
g(C{}); // ADL finds this
::N::f(C{}); // not found dispite full qualification
}
};
}
Run Code Online (Sandbox Code Playgroud)
我想我明白问题是什么,正如这里描述的内联友元函数的范围是什么?内联友元函数通常使用 ADL 找到,并且在封闭的命名空间中并不真正可见。
所以我的问题是我应该如何更改我的代码以使其工作(除了重命名 f 之一)?