And*_*nga 24 c++ gcc visual-studio-2010 unique-ptr c++11
这是一个非常简单的问题.请考虑以下代码:
#include <iostream>
#include <memory>
typedef std::unique_ptr<void> UniqueVoidPtr;
int main() {
UniqueVoidPtr p(new int);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用以下命令使用cygwin(g ++ 4.5.3)进行编译g++ -std=c++0x -o prog file.cpp就可以了.但是,使用Microsoft编译器(VS 2010或2013)进行编译时出现此错误:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\memory(2067) : error C2070: 'void': illegal sizeof operand
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\memory(2066) : while compiling class template member function 'void std::default_delete<_Ty>::operator ()(_Ty *) const'
with
[
_Ty=void
]
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\type_traits(650) : see reference to class template instantiation 'std::default_delete<_Ty>' being compiled
with
[
_Ty=void
]
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\memory(2193) : see reference to class template instantiation 'std::tr1::is_empty<_Ty>' being compiled
with
[
_Ty=std::default_delete<void>
]
foo1.cpp(7) : see reference to class template instantiation 'std::unique_ptr<_Ty>' being compiled
with
[
_Ty=void
]
Run Code Online (Sandbox Code Playgroud)
这是预期的吗?我正在编写一个类,我希望在类中有一个唯一的指针.在尝试计算类的移动构造函数的语义时,我遇到了这个(我假设因为我最终得到了我的移动构造函数编码正确:即其他错误已修复).
Jon*_*ely 22
GCC实际上有防止它的代码,但它直到最近才起作用.
GCC unique_ptr有一个静态断言default_deleter::operator(),应该拒绝不完整的类型:
static_assert(sizeof(_Tp)>0,
"can't delete pointer to incomplete type");
Run Code Online (Sandbox Code Playgroud)
但是,作为GCC支持的扩展sizeof(void),因此断言不会失败,并且因为它出现在系统头中甚至不会发出警告(除非您使用-Wsystem-headers).
我最近自己发现了这个问题所以要修复它我在10天前添加了这个:
static_assert(!is_void<_Tp>::value,
"can't delete pointer to incomplete type");
Run Code Online (Sandbox Code Playgroud)
因此,使用trunk上的最新代码,您的示例无法按照标准的要求进行编译.
ixS*_*Sci 21
MSVC是对的,而GCC错了:
标准(3.9/5):
未完全定义的对象类型和void类型是不完整的类型
标准(20.7.1.1.2/4):
如果T是不完整类型,则程序格式不正确
问题归结为:
void* p = new int;
delete p;
Run Code Online (Sandbox Code Playgroud)
看n3797 5.3.5删除,我认为delete p由于类型不匹配而导致未定义的行为,因此编译器行为是可接受的,因为代码是错误的.
注意:这不同于shared_ptr<void>,因为它使用类型擦除来跟踪传入的指针的原始类型.
| 归档时间: |
|
| 查看次数: |
9187 次 |
| 最近记录: |