c++ - C++ 中的表达式 SFINAE 和硬错误

标签 c++ c++20 sfinae

我很困惑为什么这些函数中的一个会出现硬错误,而另一个不会:

#include <utility>

template <typename ...Args>
auto ffExists1()
-> decltype(ff(std::declval<Args>()...)); // Attempts to see
    // whether you can call ff (which is not defined or declared)
    // with arguments of type Args... This works fine.

template <typename ...Args>
auto ffExists2() -> decltype(&ff); // Gives me a hard error : ff not defined
这是为什么?
另外,如何制作ffExists2工作?使用指向函数的指针可以让我确定 ff 的确切签名。而ffExists1只知道我是否可以调用ff参数类型为 Args... .
编辑:这是一个版本,其中 ffExists2取决于模板,导致相同的结果:
#include <utility>

template <typename ...Args>
auto ffExists() -> decltype(ff(std::declval<Args>()...)); //Fine

template <typename ... Args>
void SomeHelperFunc(auto (*) (Args...));

template <typename ...Args>
auto ffExists2() -> decltype(SomeHelperFunc<Args...>(&ff)); // Hard Error

最佳答案

ffExists2 , ff不依赖于模板参数,因此查找它(即通过提供的名称查找函数)在 two-phase lookup 的第一阶段完成,即当编译器第一次看到模板时,而不是模板参数被替换到它时。
正因为如此,即使 ff在此模板之后定义,这无关紧要,因为第一阶段 is already done by that point .
另一方面,在 ffExists1 ,查找 ff取决于模板参数(因为 ADL 是此查找的一部分,并且 ADL 需要知道参数的类型,即 Args... ),因此对其的查找被推迟到第二阶段,即到实例化点的模板,

at which time ADL examines function declarations that are visible from the template definition context as well as in the template instantiation context, while non-ADL lookup only examines function declarations that are visible from the template definition context (in other words, adding a new function declaration after template definition does not make it visible except via ADL).

— (c) cppreference


没有办法制作&ff依赖于模板参数,并且不可能对不依赖于模板参数的事物执行 SFINAE 检查。任何尝试都将受到以下因素的阻碍:

[temp.res.general]/6.1

The program is ill-formed, no diagnostic required, if:

— no valid specialization can be generated for a template ...



你会认为 C++20 requires可以提供帮助,因为您可以在没有任何模板的情况下使用它,但是唉:

[expr.prim.req.general]/5

...

[Note 1: If a requires-expression contains invalid types or expressions in its requirements, and it does not appear within the declaration of a templated entity, then the program is ill-formed. — end note]

If the substitution of template arguments into a requirement would always result in a substitution failure, the program is ill-formed; no diagnostic required.

关于c++ - C++ 中的表达式 SFINAE 和硬错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66770807/

相关文章:

c++ - 如何将 unique_ptr 与前向声明类型一起使用?

c++ - 格式良好的类定义示例,其中包含编译器删除的默认特殊成员函数

c++ - ranges::views 如何实现 O(1) 复杂度?

c++ - 为什么这些函数模板与实例化都不匹配?

c++ - 整型/实型的模板结构特化

c++ - 谁需要八进制表示?

c++ - 模板类的类型定义?

c++ - 显式程序在 msvc 中有效,但在 gcc 中无效

c++ - 模板类中的类模板特化

c++ - 在 C++ 中计算滚动/移动平均值