![](/img/trans.png)
[英]How to understand the following usage of boost::enable_if and boost::disable_if
[英]Boost enable/disable_if function pair's order matters?
我正在编写一个递归函数,其结束条件由模板参数确定。 我正在使用boost::enable_if
和boost::disable_if
来为空的基本情况切换递归函数(以防止麻烦的无限实例化循环)。
问题在于它似乎取决于我定义这些功能的顺序:
#include <boost/utility.hpp>
template <unsigned a, unsigned b>
typename boost::disable_if_c<a == b>::type f()
{
f<a+1,b>();
}
template <unsigned a, unsigned b>
typename boost::enable_if_c<a == b>::type f()
{
}
int main()
{
f<0,5>();
}
编译器(g ++ 4.6)失败,并显示以下错误:
test.cpp:7:5: error: no matching function for call to ‘f()’
test.cpp:7:5: note: candidate is:
test.cpp:5:44: note: template<unsigned int a, unsigned int b> typename boost::disable_if_c<(a == b)>::type f()
由于某种原因,只有禁用的功能才是候选功能,看不到已启用的功能。
如果我切换顺序,则定义了两个函数,它将在有问题且没有警告的情况下进行编译:
#include <boost/utility.hpp>
template <unsigned a, unsigned b>
typename boost::enable_if_c<a == b>::type f()
{
}
template <unsigned a, unsigned b>
typename boost::disable_if_c<a == b>::type f()
{
f<a+1,b>();
}
int main()
{
f<0,5>();
}
为什么是这样? 到实例化发生时( main
),编译器已经看到了这两个函数,不必在乎谁先行。 至少那是我的想法。
你说
到实例化发生时(主要),编译器已经看到了这两个函数,并且不必在乎谁先入行。
这是不对的,我认为这就是让您绊倒的原因。 main中实例化的只是f<0,5>
,其余实例化发生在您调用它们的位置,即第一个f
函数模板中。 从那里看不到第二个,所以它不能参与重载解析。
所以,会发生什么:
// imagine we're inside f<4,5> instantiation
template <unsigned a, unsigned b>
typename boost::disable_if_c<a == b>::type f()
{
f<a+1,b>(); // <-- here we attempt to instantiate f<5,5> ...
// but it gets disabled!
// and there is no other f visible here, it's defined just below
}
如果切换定义的顺序,则enable_if
版本可见,并在需要时插入。
实际上,您对函数是模板感到困惑。 这与它无关。 由于相同的原因,以下代码也不会编译。
void foo(int)
{
foo("");
}
void foo(char const*)
{
}
int main()
{
foo(42);
}
顺序很重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.