This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4628. std::invoke forwarding xvalues of incomplete type

Section: 21.3.8.7 [meta.trans.other] Status: New Submitter: Jay Ghiron Opened: 2026-10-05 Last modified: 2026-10-13

Priority: Not Prioritized

View other active issues in [meta.trans.other].

View all other issues in [meta.trans.other].

View all issues with New status.

Discussion:

Consider the following program:

#include <utility>
#include <functional>

extern struct S s;

void f(S&&){}

int main() {
  f(std::move(s));
  std::invoke(f, std::move(s));
}

Assume that s is defined in another translation unit. The first call to f is clearly defined, and all compilers accept that. However, there is disagreement among implementations about whether or not the second call to f is valid when using invoke. libstdc++ rejects it, while libc++ and MSVC's STL accept it. This appears to be due to invoke referencing invoke_result which specifies preconditions that make this undefined. 22.10.5 [func.invoke] defines invoke as

template<class F, class... Args>
  constexpr invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
    noexcept(is_nothrow_invocable_v<F, Args...>);

21.3.8.7 [meta.trans.other] has the following precondition on invoke_result:

Preconditions: Fn and all types in the template parameter pack ArgTypes are complete types, cv void, or arrays of unknown bound.

Fn and ArgTypes are F and Args respectively. In this call to invoke Args is deduced to have one type which is the incomplete type S. Therefore it does not satisfy the precondition. Was it really intended to make this usage of invoke undefined? Note that the following is defined and accepted by all compilers:

#include <utility>
#include <functional>

using T = struct U[];

extern T t;

void g(T&&){}

int main() {
  g(std::move(t));
  std::invoke(g, std::move(t));
}

Assume that t is defined in another translation unit. Giving the array type a length causes the implementation disagreement and undefined behavior again.

See also LWG 2939(i) and others.

Proposed resolution: