简体   繁体   English

Boost enable / disable_if函数对的顺序重要吗?

[英]Boost enable/disable_if function pair's order matters?

I'm writing a recursive function whose end condition is determined by template parameters. 我正在编写一个递归函数,其结束条件由模板参数确定。 I'm using boost::enable_if and boost::disable_if to switch out the recursive function for an empty base case (to prevent that tiresome infinite instantiation loop). 我正在使用boost::enable_ifboost::disable_if来为空的基本情况切换递归函数(以防止麻烦的无限实例化循环)。
The problem is that it seems to depend on the order which I define these functions: 问题在于它似乎取决于我定义这些功能的顺序:

    #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>();
    }

the compiler (g++4.6) fails with the error: 编译器(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()

for some reason there's only the disabled function as a candidate, the enabled one isn't seen. 由于某种原因,只有禁用的功能才是候选功能,看不到已启用的功能。

If I switch the order the two functions are defined it compiles with issue and without warnings: 如果我切换顺序,则定义了两个函数,它将在有问题且没有警告的情况下进行编译:

    #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>();
    }

Why is this? 为什么是这样? By the time the instantiation happens (in main ) the compiler has seen both functions and shouldn't care who got in line first. 到实例化发生时( main ),编译器已经看到了这两个函数,不必在乎谁先行。 At least that's what I thought. 至少那是我的想法。

You say 你说

By the time the instantiation happens (in main) the compiler has seen both functions and shouldn't care who got in line first. 到实例化发生时(主要),编译器已经看到了这两个函数,并且不必在乎谁先入行。

This is not true and I think that's what's tripping you up. 这是不对的,我认为这就是让您绊倒的原因。 What's instantiated in main is just f<0,5> , the rest of instantiations happen where you call them, inside first f function template. main中实例化的只是f<0,5> ,其余实例化发生在您调用它们的位置,即第一个f函数模板中。 The second one isn't visible from there so it can't participate in overload resolution. 从那里看不到第二个,所以它不能参与重载解析。

So, what happens: 所以,会发生什么:

// 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
}

If you switch the order of definitions, the enable_if version is visible and it kicks in when needed. 如果切换定义的顺序,则enable_if版本可见,并在需要时插入。

You're getting mixed up by fact that your functions are templates. 实际上,您对函数是模板感到困惑。 That doesn't have anything to do with it. 这与它无关。 The following also doesn't compile, and for the same reason. 由于相同的原因,以下代码也不会编译。

void foo(int)
{
  foo("");
}

void foo(char const*)
{
}

int main()
{
  foo(42);
}

Order matters. 顺序很重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM