gpt4 book ai didi

c++ - std::is_invocable 的奇怪行为

转载 作者:行者123 更新时间:2023-12-01 14:34:03 27 4
gpt4 key购买 nike

我在以下程序中遇到 std::is_invocable 问题:

#include <iostream>
#include <type_traits>

void g() {}

template<bool B, typename T>
void f(T t) {
if constexpr (B)
g(t);
}

int main() {
std::cerr << std::boolalpha <<
std::is_invocable_v<decltype(&f<true, int>), int> << std::endl;
}

我希望程序输出为 false,因为 f 无法实例化。但是,GCC(自 10.0.1 20200224 起)未编译,错误消息为

test.cpp: In instantiation of 'void f(T) [with bool B = true; T = int]':
test.cpp:14:51: required from here
test.cpp:9:10: error: too many arguments to function 'void g()'
9 | g(t);
| ~^~~
test.cpp:4:6: note: declared here
4 | void g() {}
|

和 Clang(从 11.0.0 开始)甚至打印 true

在这种情况下正确的行为是什么?

最佳答案

问题归结为:是否 decltype(&f<true, int>)实际上实例化f<true, int>

如果是,则程序格式错误,因为该实例化格式错误(无法按要求使用 g 调用 int)。

如果不是,则正确答案为 invocable_vtrue - 因为函数体上没有 SFINAE,并且函数的签名明确允许此调用。

似乎 gcc 认为是(和硬错误)而 clang 认为不是(并产生 true )。我认为clang在这里是正确的。我们的规则是:

[temp.inst]/10 :

If a function template or a member function template specialization is used in a way that involves overload resolution, a declaration of the specialization is implicitly instantiated ([temp.over]).

[temp.inst]/11 :

An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, a static data member of a class template, or a substatement of a constexpr if statement ([stmt.if]), unless such instantiation is required.

我们这里确实涉及重载解析(函数地址),但这只是实例化函数模板的声明。我认为没有什么需要实例化函数模板的定义( f 返回 void ,而不是类似 auto 的东西),所以 gcc 在这里过于急切地实例化它。

也就是说,它当然不应该产生 false .

关于c++ - std::is_invocable 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60440755/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com