Does std::reference_wrapper<T>
allow T
to be incomplete, in the same way that a T&
can be dealt with without T
being complete?
GCC 4.9 accepts the following:
#include <functional>
struct woof;
struct test
{
test(woof& w) : w(w) {}
std::reference_wrapper<woof> w;
};
struct woof
{
int a;
};
int main()
{
woof w;
test t = w; // (braced-init would be better, but VS2012!)
}
But MSVS 2012 rejects it with the following message:
Error 1 error C2139: 'woof' : an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_abstract' c:\program files (x86)\microsoft visual studio 11.0\vc\include\type_traits 755 1 test3
I suspect this is because the op()
needs the full type, but the standard doesn't appear to specify either way.
Which, if either, of these implementations is following standard mandates?
N3936 §17.6.4.8 Other functions [res.on.functions]:
1 In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C++ standard library depends on components supplied by a C++ program. If these components do not meet their requirements, the Standard places no requirements on the implementation.
2 In particular, the effects are undefined in the following cases:
- ...
- if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.
A quick scan through 20.9.3 Class template reference_wrapper
[refwrap] reveals no such specific exception for reference_wrapper
, so your program has undefined behavior. Both implementations are conforming.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With