Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

In this concept definition:

#include <utility>

template<class Func, class Ret, class... Args>
concept Invokable = requires(Func f) {
    { f(std::declval<Args>()...) } -> Ret;
};

when instantiated like this:

static_assert(Invokable<decltype([](int){}), void, int>);

gcc-9.0.1 (trunk) dumps (well, the Standard Library implementation to be precise):

$ 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,
     |                                               ^~~~~~

demo: https://godbolt.org/z/D0ygU4

Is it wrong to reject this code? If not, what did I do wrong? If yes, where should one report this bug?


Notes

This is accepted

template<auto f, class... Args>
constexpr auto size_of_return_type = sizeof(f(std::declval<Args>()...));

when instantiated like so:

static_assert(sizeof(int) == size_of_return_type<[](int){ return 0; }, int>);

Demo: https://godbolt.org/z/gYGk8U

Latest C++2a draft states:

[expr.prim.req]/2 A requires-expression is a prvalue of type bool whose value is described below. Expressions appearing within a requirement-body are unevaluated operands.

like image 829
YSC Avatar asked Apr 24 '19 15:04

YSC


1 Answers

Is it wrong to reject this code?

Yes, concepts are never evaluated, as evidenced in the quote you're citing. This is gcc bug 68781 and gcc bug 82171.

Note that there's no reason to use declval within concepts. This is more straightforward:

template<class Func, class Ret, class... Args>
concept InvokableR = requires(Func&& f, Args&&... args) {
    { f(std::forward<Args>(args)...) } -> Ret;
};

declval exists because you need some expression of some type and you can't just write T() because that requires a default constructor. Concepts give you that ability as a first-class language feature. Still need the forward though.

like image 178
Barry Avatar answered Nov 11 '22 00:11

Barry