非终止递归函数模板实例化不会产生替换失败

时间:2014-10-05 16:34:45

标签: c++ overloading sfinae overload-resolution

考虑以下代码(基于article Xeo)来确定函数重载的优先级:

template <bool condition>
using EnableIf = typename std::enable_if<condition, int>::type;


template <std::size_t n>
struct OverloadPriority
    : OverloadPriority<n - 1>
{}; 

template <>
struct OverloadPriority<0> {};



namespace impl {
    template <int x, EnableIf<x % 11 == 0>...>
    void f(OverloadPriority<5>) { std::cout << x << " is multiple of 11\n"; }

    template <int x, EnableIf<x % 7 == 0>...>
    void f(OverloadPriority<4>) { std::cout << x << " is multiple of 7\n"; }

    template <int x, EnableIf<x % 5 == 0>...>
    void f(OverloadPriority<3>) { std::cout << x << " is multiple of 5\n"; }

    template <int x, EnableIf<x % 3 == 0>...>
    void f(OverloadPriority<2>) { std::cout << x << " is multiple of 3\n"; }

    template <int x, EnableIf<x % 2 == 0>...>
    void f(OverloadPriority<1>) { std::cout << x << " is multiple of 2\n"; }

    template <int x>
    void f(OverloadPriority<0>) { std::cout << x << " is multiple of 1\n"; }
}

template <int x>
auto f()
    -> decltype(impl::f<x>(OverloadPriority<5>{}))
{
    return impl::f<x>(OverloadPriority<5>{});
}

int main() {
    f<10>();
    return 0;
}

按预期工作。

现在,我想将f的{​​{1}}与调度impl一起带入文件范围,如下所示:

f

现在gcc-4.8.1告诉我最后一次调度template <int x, EnableIf<x % 11 == 0>...> void f(OverloadPriority<5>) { std::cout << x << " is multiple of 11\n"; } template <int x, EnableIf<x % 7 == 0>...> void f(OverloadPriority<4>) { std::cout << x << " is multiple of 7\n"; } template <int x, EnableIf<x % 5 == 0>...> void f(OverloadPriority<3>) { std::cout << x << " is multiple of 5\n"; } template <int x, EnableIf<x % 3 == 0>...> void f(OverloadPriority<2>) { std::cout << x << " is multiple of 3\n"; } template <int x, EnableIf<x % 2 == 0>...> void f(OverloadPriority<1>) { std::cout << x << " is multiple of 2\n"; } template <int x> void f(OverloadPriority<0>) { std::cout << x << " is multiple of 1\n"; } template <int x> auto f() -> decltype(f<x>(OverloadPriority<5>{})) { return f<x>(OverloadPriority<5>{}); } 超过了尾随返回类型中的最大模板实例化深度:

f()

我希望template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) substituting 'template<int x> decltype (f<x>(OverloadPriority<5ul>{})) f() [with int x = 10]' -> decltype(f<x>(OverloadPriority<5>{})) 本身能够安静地进行SFINAE。为什么这是一个错误而不仅仅是替换失败?

0 个答案:

没有答案