FilippoL
FilippoL

Reputation: 160

Does the C++ standard explicitly allow/disallow instantiating std::function with incomplete types?

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

Answers (1)

NathanOliver
NathanOliver

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

Related Questions