Movatterモバイル変換


[0]ホーム

URL:



This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofC++14 status.

2149. Concerns about 20.8/5

Section: 22.10[function.objects]Status:C++14Submitter: Scott MeyersOpened: 2012-02-15Last modified: 2016-01-28

Priority:Not Prioritized

View all otherissues in [function.objects].

View all issues withC++14 status.

Discussion:

22.10[function.objects] p5 says:

To enable adaptors and other components to manipulate function objects that take one or two argumentsit is required that the function objects correspondingly provide typedefsargument_type andresult_type for function objects that take one argument andfirst_argument_type,second_argument_type, andresult_type for function objects that take two arguments.

I have two concerns about this paragraph. First, the wording appears to prescribe a requirement for all function objects in valid C++ programs, but it seems unlikely that that is the intent. As such, the scope of the requirement is unclear. For example, there is no mention of these typedefs in the specification for closures (5.1.2), and Daniel Krügler has explained in the thread athttp://tinyurl.com/856plkn that conforming implementations can detect the difference between closures with and without these typedefs. (Neither gcc 4.6 nor VC10 appear to define typedefs such asresult_type for closure types. I have not tested other compilers.)

Second, the requirement appears to be unimplementable in some cases, notably for function objects returned fromstd::bind, as Howard Hinnant explains in the thread athttp://tinyurl.com/6q5bos4.

From what I can tell, the standard already defines which adaptability typedefs must be provided by various kinds of function objects in the specifications for those objects. Examples include the function objects specified in 22.10.6[refwrap]- [negators]. I therefore suggest that 22.10[function.objects]/5 simply be removed from the standard. I don't think it adds anything except opportunities for confusion.

[2012-10 Portland: Move to Open]

This wording caused confusion earlier in the week when reviewing Stefan's paper ongreater<>.

This phrasing sounds normative, but is actually descriptive but uses unfortunate wording.

The main reason this wording exists is to document the protocol required to support the legacy bindersin Annex D.

Stefan points out thatunary_negate andbinary_negate have not been deprecated and relyon this. He plans a paper to remove this dependency.

Consensus that this wording is inadequate, confusing, and probably should be removed. However, thatleaves a big hole in the specification for the legacy binders, that needs filling.

While not opposed to striking this paragraph, we will need the additional wording to fix the openninghole before this issue can move forward.

[2013-04-14 STL provides rationale]

Rationale:

I've concluded that Scott's original proposed resolution was correct and complete. There are two sides to this story: the producers and the consumers of these typedefs.

Producers: As Scott noted, the Standard clearly documents which function objects must provide these typedefs. Some function objects must provide them unconditionally (e.g.plus<T> (forT != void), 22.10.7[arithmetic.operations]/1), some conditionally (e.g.reference_wrapper<T>, 22.10.6[refwrap]/2-4), and some don't have to provide them at all (e.g. lambdas, 7.5.6[expr.prim.lambda]). These requirements are clear, so we shouldn't change them or even add informative notes. Furthermore, because these typedefs aren't needed in the C++11 world withdecltype/perfect forwarding/etc., we shouldn't add more requirements to provide them.

Consumers: This is what we were concerned about at Portland. However, the consumers also clearly document their requirements in the existing text. For example,reference_wrapper<T> is also a conditional consumer, and 22.10.6[refwrap] explains what typedefs it's looking for. We were especially concerned about the old negators and the deprecated binders, but they're okay too. [negators] clearly says thatunary_negate<Predicate> requiresPredicate::argument_type to be a type, andbinary_negate<Predicate> requiresPredicate::first_argument_type andPredicate::second_argument_type to be types. (unary_negate/binary_negate provideresult_type but they don't consume it.) 99 [depr.lib.binders] behaves the same way withFn::first_argument_type,Fn::second_argument_type, andFn::result_type. No additional wording is necessary.

A careful reading of 22.10[function.objects]/5 reveals that it wasn't talking about anything beyond the mere existence of the mentioned typedefs — for example, it didn't mention that the function object's return type should beresult_type, or even convertible toresult_type. As the producers and consumers are certainly talking about the existence of the typedefs (in addition to clearly implying semantic requirements), we lose nothing by deleting the unnecessary paragraph.

[2013-04-18, Bristol]

Previous wording:

Remove 22.10[function.objects] p5:

To enable adaptors and other components to manipulate function objects that take one or two argumentsit is required that the function objects correspondingly provide typedefsargument_type andresult_type for function objects that take one argument andfirst_argument_type,second_argument_type, andresult_type for function objects that take two arguments.

Proposed resolution:

This wording is relative toN3485.

Edit 22.10[function.objects] p5:

[Note:To enable adaptors and other components to manipulate function objects that take one or two argumentsit is required that the function objectsmany of the function objects in this clause correspondingly provide typedefsargument_type andresult_type for function objects that take one argument andfirst_argument_type,second_argument_type, andresult_type for function objects that take two arguments.end note]


[8]ページ先頭

©2009-2026 Movatter.jp