Reputation: 160
Consider something like this:
class A;
std::function<A(A)> f;
This is clearly something you want to do in your program. Any major compiler accepts that without problems.
My question is: is it technically allowed by the standard?
If I see correctly, the section
20.5.4.8 Other functions
prohibits use of template parameters of incomplete type at instantiation, unless otherwise specified (and not only for containers).
In the section about std::function
or <functional>
I see no reference to allowing this.
Does somebody know where and if this is explicitly written in the standard?
Upvotes: 5
Views: 118
Reputation: 181057
This is covered by the library catch-all [res.on.functions]/2
In particular, the effects are undefined in the following cases: [...]
- if an incomplete type ([basic.types]) is used as a template argument when instantiating a template component or evaluating a concept, unless specifically allowed for that component.
Since nothing in [func.wrap.func] overrides this, it is undefined behavior to have an incomplete function type.
As an example of what an you would need to see in [func.wrap.func] lets look at [unique.ptr]/4
[...] The template parameter T of unique_ptr may be an incomplete type.
Here it explicitly states that an incomplete type is allowed. We would need something like that in [func.wrap.func] and we don't, so we fall back to [res.on.functions]/2 and it being undefined behavior.
Upvotes: 2