C++ 我可以实例化一个std::reference\u包装器<;T>;其中T是不完整类型?
C++ 我可以实例化一个std::reference\u包装器<;T>;其中T是不完整类型?,c++,c++11,language-lawyer,incomplete-type,C++,C++11,Language Lawyer,Incomplete Type,std::reference\u wrapper是否允许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
std::reference\u wrapper
是否允许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!)
}
#包括
结构纬;
结构测试
{
测试(纬&纬):w(w){}
标准::参考包装纸w;
};
结构纬
{
INTA;
};
int main()
{
纬纱;
测试t=w;//(带括号的init会更好,但VS2012!)
}
但MSVS 2012拒绝了它,并发出以下消息:
错误1错误C2139:“woof”:不允许未定义的类作为编译器内部类型trait“\uuu is\u abstract”的参数c:\program files(x86)\microsoft visual studio 11.0\vc\include\type\u traits 755 1 test3
我怀疑这是因为op()
需要完整类型,但标准似乎没有指定任何一种方式
这些实现中的哪一个符合标准要求?N3936§17.6.4.8其他功能[res.on.functions]: 在某些情况下(Puxor函数,Helter函数,用于标准库模板组件的类型的操作),C++标准库依赖于C++程序提供的组件。如果这些组件不满足其要求,则标准不会对实现提出任何要求 2特别是在以下情况下,影响未定义:
- 如果在实例化模板组件时将不完整类型(3.9)用作模板参数, 除非该组件特别允许
快速浏览20.9.3类模板
reference\u wrapper
[refwrap]不会发现reference\u wrapper
的此类特定异常,因此您的程序具有未定义的行为。这两种实现都是一致的。我不知道,但我的赌注不是在MSVC上。注意,MSVC失败,不管标准怎么说:不在MSVC11+上编译,这要归功于是抽象的
测试。该死,太慢了+1顺便说一句:我认为这是一个不完整类型应该被允许的情况。似乎只有智能指针类型例外。我认为将它也用于reference\u wrapper
是很有意义的,因为它可能很有用,而且实现起来也很简单(因为它通常只是指针周围的一个包装,就像智能指针一样)。整个不完整类型问题是C++标准中的一个非常薄弱的问题(对于库组件和模板规则),需要更好的规范。类似于更清晰的规则和所需的诊断/错误,而不是UB。@重复数据消除程序允许不完整类型的问题是,reference\u wrapper
必须遵守旧的一元函数
/二进制函数
协议,以实现向后兼容性。为此,它需要根据模板参数的类型定义各种typedef,例如[refwrap]/3:“模板实例化。。。应定义<仅当类型T
为以下任一类型时,才将code>argument\u type作为T1
的同义词:。。。具有成员类型参数类型的类类型;类型T1
是T::argument\u type
。