我可以实例化一个std :: reference_wrapper <T>,其中T是一个不完整的类型?

Lig*_*ica 11 c++ language-lawyer incomplete-type c++11

是否std::reference_wrapper<T>允许T不完整,在一个同样的方式T&可以不进行处理T是完全?

GCC 4.9接受以下内容:

#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!)
}
Run Code Online (Sandbox Code Playgroud)

但是MSVS 2012拒绝了它,并带有以下消息:

错误1错误C2139:'woof':不允许将未定义的类作为编译器内部类型特征的参数'__is_abstract'c:\ program files(x86)\ microsoft visual studio 11.0\vc\include\type_traits 755 1 test3

我怀疑这是因为op()需要完整的类型,但该标准并没有出现指定两种方式.

这些实现中的哪一个遵循标准要求?

Cas*_*sey 15

N3936§17.6.4.8 其他功能[res.on.functions]:

1在某些情况下(替换函数,处理函数,用于实例化标准库模板组件的类型的操作),C++标准库依赖于C++程序提供的组件.如果这些组件不符合要求,则标准对实施没有要求.

2特别是,在下列情况下,效果未定义:

  • ...
  • 如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非特别允许该组件.

快速浏览20.9.3 类模板reference_wrapper[refwrap]显示没有这样的特定异常reference_wrapper,因此您的程序具有未定义的行为.两种实现都是一致的.

  • @Deduplicator允许不完整类型的问题是`reference_wrapper`必须符合旧的`unary_function` /`binary_function`协议才能实现向后兼容性.为此,需要根据模板参数的类型定义各种typedef,例如[refwrap]/3:"模板实例化......应将...`argument_type`定义为`T1`的同义词类型`T`是以下任何一种:...具有成员类型`argument_type`的类类型;类型`T1`是`T :: argument_type`.". (5认同)