Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
287 views
in Technique[技术] by (71.8m points)

c++ - Lambda capturing constexpr object

GCC 4.7.2 compiles this:

constexpr int i = 5;
[]{ std::integral_constant< int, i >(); }; // nonstandard: i not captured

but not this:

constexpr int i = 5;
[&i]{ std::integral_constant< int, i >(); }; // GCC says i not constexpr

The latter example appears correct to me, according to C++11 §5.1.2/15:

An entity is captured by reference if it is implicitly or explicitly captured but not captured by copy. It is unspecified whether additional unnamed non-static data members are declared in the closure type for entities captured by reference.

It seems the captured object i inside the lambda refers to the variable in the enclosing scope, which is constexpr, not merely a const reference.

The standard explicitly says that the use of a by-value capture is transformed into a use of the corresponding member of the lambda object. And I think that 5.1.2 hints that my interpretation is correct.

Is there anything that explicitly says that whether a capture by reference refers to the object in the enclosing scope or a reference?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The second template-argument to std::integral_constant< int, i > is for a template-parameter of non-type form, specifically of integral or enumeration type (14.3.2p1 bullet 1) and so must be a converted constant expression of type int.

In a lambda-expression, implicit capture occurs when an entity is odr-used in the compound statement (5.1.2p11); use of a converted constant expression in an explicit template instantiation is not odr-use (3.2p3), so the first example is valid.

In the second example, I think gcc is incorrect to reject it; 5.1.2p17 says in a note that:

An id-expression that is not an odr-use refers to the original entity, never to a member of the closure type.

Although the paragraph as a whole is discussing capture by copy, there's no reason not to apply this rule to capture by reference as well. It's unsurprising that the standard is unclear on this; there's really no reason to capture an entity that can be used in a converted constant expression by reference.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...