繁体   English   中英

gcc是否在这个概念定义中错误地评估了std :: declval?

[英]Is gcc wrongly evaluating std::declval in this concept definition?

在这个概念定义中:

#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(trunk)转储(确切地说,标准库实现):

 $ 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 A requires-expression是bool类型的prvalue,其值如下所述。 出现在需求体内的表达式是未评估的操作数。

拒绝这段代码是错误的吗?

是的,概念永远不会被评估,正如您引用的引用中所证明的那样。 这是gcc bug 68781gcc bug 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM