我试图了解如何在编译时选择正确的重载函数模板,但编译器让我很难过。我可以让它工作,但我不明白发生了什么。让我解释。
我有两个结构 A 和 B,如下所示。一个具有特殊功能,另一个具有正常功能。
struct A
{
void special() { std::cout << "special called.\n"; }
};
struct B
{
void normal() { std::cout << "normal called.\n"; }
};
我的意图是有一种机制,它在编译时根据特殊函数是否可用来选择正确的重载函数模板。我运行了两个函数,它们将结构作为参数,因此它们可以调用适当的函数。
template<class Func, Func f> struct Sfinae {};
template <typename U>
static void run(U& u, Sfinae<void (U::*)(), &U::special>* = 0)
{
u.special();
}
template <typename U>
static void run(U& u, ...)
{
u.normal();
}
我已经用以下方法对此进行了测试,得到了各种结果:
int main()
{
A a;
run<A>(a, 0); // works
run<A>(a); // ERROR: ambiguous overloaded function
run(a, 0); // ERROR: A has no member normal
run(a); // ERROR: ambiguous overloaded function
B b;
run<B>(b, 0); // works
run<B>(b); // works
run(b, 0); // works
run(b); // works
return 0;
}
我想在run(a)
没有任何额外参数或 <> 的情况下使用它。当这不起作用时,我的代码有问题吗?
另外,我有兴趣了解这里发生了什么以及为什么会推断出这样的事情,所以我需要给予<A>
而A
不是给予B
?我不知道标准说什么以及编译器之间是否有所不同,但至少 Linux 上的 gcc4.4.4 和 Mac 上的 gcc 4.0.1 像我所描述的那样工作。
有人可以对此有所了解吗?谢谢!