为什么ADL没有找到功能模板?

为什么ADL没有找到功能模板?

C ++规范的哪一部分限制参数依赖查找在相关命名空间集合中查找函数模板?换句话说,为什么main下面的最后一次调用无法编译?


namespace ns {

    struct foo {};

    template<int i> void frob(foo const&) {}

    void non_template(foo const&) {}

}


int main() {

    ns::foo f;

    non_template(f); // This is fine.

    frob<0>(f); // This is not.

}


慕标琳琳
浏览 347回答 3
3回答

慕的地10843

这部分解释了它:C ++标准03 14.8.1.6:[注意:对于简单的函数名称,即使函数名称在调用范围内不可见,依赖于参数的查找(3.4.2)也适用。这是因为调用仍然具有函数调用的语法形式(3.4.1)。但是当使用带有显式模板参数的函数模板时,除非在调用点处有一个具有该名称的函数模板,否则调用没有正确的语法形式。如果看不到这样的名称,则调用语法不完善,并且参数依赖查找不适用。如果某些此类名称可见,则应用依赖于参数的查找,并且可以在其他名称空间中找到其他函数模板。namespace&nbsp;A&nbsp;{ &nbsp;&nbsp;struct&nbsp;B&nbsp;{&nbsp;}; &nbsp;&nbsp;template<int&nbsp;X>&nbsp;void&nbsp;f(B);}namespace&nbsp;C&nbsp;{ &nbsp;&nbsp;template<class&nbsp;T>&nbsp;void&nbsp;f(T&nbsp;t);}void&nbsp;g(A::B&nbsp;b)&nbsp;{ &nbsp;&nbsp;f<3>(b);&nbsp;&nbsp;&nbsp;&nbsp;//ill-formed:&nbsp;not&nbsp;a&nbsp;function&nbsp;call &nbsp;&nbsp;A::f<3>(b);&nbsp;//well-formed &nbsp;&nbsp;C::f<3>(b);&nbsp;//ill-formed;&nbsp;argument&nbsp;dependent&nbsp;lookup &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;applies&nbsp;only&nbsp;to&nbsp;unqualified&nbsp;names &nbsp;&nbsp;using&nbsp;C::f; &nbsp;&nbsp;f<3>(b);&nbsp;&nbsp;&nbsp;&nbsp;//well-formed&nbsp;because&nbsp;C::f&nbsp;is&nbsp;visible;&nbsp;then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;A::f&nbsp;is&nbsp;found&nbsp;by&nbsp;argument&nbsp;dependent&nbsp;lookup}

慕尼黑8549860

从c ++ 20开始,adl与显式函数模板一起工作也很好。以下是提议:&nbsp;P0846R0:不可见的ADL和功能模板:不要求用户使用template关键字,而是建议对查找规则进行修订,以便正常查找产生无结果或找到一个或多个函数且后面跟aa“<”的名称将被视为如果找到了函数模板名称并且将导致执行ADL。目前,只有GCC 9实现了此功能,因此您的示例可以编译。live demo。
打开App,查看更多内容
随时随地看视频慕课网APP