c++ - gcc 在这个概念定义中是否错误地评估了 std::declval ?
问题描述
在这个概念定义中:
#include <utility>
template<class Func, class Ret, class... Args>
concept Invokable = requires(Func f) {
{ f(std::declval<Args>()...) } -> Ret;
};
当像这样实例化时:
static_assert(Invokable<decltype([](int){}), void, int>);
gcc-9.0.1(主干)转储(准确地说是标准库实现):
$ g++ -O2 -std=c++2a -fconcepts -Wall -Wextra -Werror -c tu1.cpp error: static assertion failed: declval() must not be used! 2204 | static_assert(__declval_protector<_Tp>::__stop, | ^~~~~~
演示:https ://godbolt.org/z/D0ygU4
拒绝这个代码有错吗?如果不是,我做错了什么?如果是,应该在哪里报告这个错误?
笔记
这被接受
template<auto f, class... Args>
constexpr auto size_of_return_type = sizeof(f(std::declval<Args>()...));
当像这样实例化时:
static_assert(sizeof(int) == size_of_return_type<[](int){ return 0; }, int>);
演示:https ://godbolt.org/z/gYGk8U
最新的 C++2a 草案指出:
[expr.prim.req]/2
requires-expression 是 bool 类型的纯右值,其值如下所述。出现在需求主体中的表达式是未计算的操作数。
解决方案
拒绝这个代码有错吗?
是的,从不评估概念,正如您引用的引文所证明的那样。这是gcc 错误 68781和gcc 错误 82171。
请注意,没有理由declval
在概念内使用。这更直接:
template<class Func, class Ret, class... Args>
concept InvokableR = requires(Func&& f, Args&&... args) {
{ f(std::forward<Args>(args)...) } -> Ret;
};
declval
存在是因为您需要某种类型的表达式,而您不能只写T()
,因为这需要默认构造函数。概念为您提供一流的语言功能。不过还是需要的forward
。
推荐阅读
- python - Python discord bot“找不到命令'ban'”错误
- c# - c# 在通用控制器上使用自定义过滤器属性
- python - Numpy Where Multiple Conditions ,无法将 dtyped [object] 数组与 [bool] 类型的标量进行比较
- javascript - hashRouter React 破坏 AnimatePresence(Framer-Motion) 退出动画
- r - 在 R 版本 4 中,Anova 无法将线性混合回归基础模型与其他具有不同变量的模型进行比较
- sparql - SPARQL 查询以获取所有“叶”类/最低级别的类
- mysql - Execute MySQL Trigger only when specific NEW value exists
- python - Python Locust 自定义客户端函数没有属性事件
- php - 使用 uasort 排序(多个条件)
- sql - 打开 Excel 工作簿上的 VBA 宏中的 SQL 查询 - 缓存问题