[英]False positive with is_copy_constructible on vector<unique_ptr>
[英]Why does is_copy_constructible return true for unique_ptr in MSVC12
我原以为这个静态断言会被激发:
#include <type_traits>
#include <memory>
int main() {
static_assert(std::is_copy_constructible<std::unique_ptr<int>>::value, "UPtr has copy constructor?");
}
但事实并非如此。
使用MSVC12编译:
用于x64的Microsoft(R)C / C ++优化编译器版本18.00.31101
应该触发static_assert
, std :: unique_ptr有一个隐式删除的拷贝构造函数,所以这是一个bug。 这看起来与此错误报告相关, std :: is_copy_constructible已损坏 :
(1)对于具有已删除副本构造函数的类型,std :: is_copy_constructible返回true。
(2)对于组成不可复制构造类型的类型,std :: is_copy_constructible返回true。
而回应是:
感谢您报告此错误。 我们已经修复了它,修复程序将在2013年后的Visual Studio的下一个主要版本中提供。
此外,请参阅此错误报告: std :: is_copy_constructible无法正常工作 。
请注意,断言在使用最新版本的Visual Studio的webcompiler上触发。 最后一次更新是在Dec 3, 2015
年Dec 3, 2015
。 断言也会对clang( 看到它直播 )和gcc发起攻击。
我发现了一个错误报告: std :: is_copy_constructible的一个奇怪的行为,它与你的代码非常相似:
static_assert(std::is_copy_constructible<std::unique_ptr<int>>::value, "");
那里的回应是:
感谢您报告此错误。 我们已经修复了它,修复程序在VS 2015 Preview中可用。
不清楚,修复了哪个版本的Visual Studio。一个响应说明2013年末版本,而后一个版本说2015预览版。
以下是使类不可复制的四种方法:
#include <stdio.h>
#include <type_traits>
class A {
public:
A(const A&) = delete;
void operator=(const A&) = delete;
};
class B {
private:
B(const B&) = delete;
void operator=(const B&) = delete;
};
class C {
public:
C(const C&) = delete;
void operator=(const C&) = delete;
void operator=(C) = delete;
};
class D {
private:
D(const D&) = delete;
void operator=(const D&) = delete;
void operator=(D) = delete;
};
int main() {
printf("%d %d\n", std::is_copy_constructible<A>::value, std::is_copy_assignable<A>::value);
printf("%d %d\n", std::is_copy_constructible<B>::value, std::is_copy_assignable<B>::value);
printf("%d %d\n", std::is_copy_constructible<C>::value, std::is_copy_assignable<C>::value);
printf("%d %d\n", std::is_copy_constructible<D>::value, std::is_copy_assignable<D>::value);
}
在MSVC2013 x64(x64的18.00.40629 for x64
)上,它打印:
1 1 //A
0 1 //B
1 0 //C
0 0 //D
在适当的编译器上,所有八个值必须为零。
不幸的是,这并没有提供一种解决MSVC2013中的错误的好方法,即使对于您自己的类也是如此。 因为如果声明赋值运算符按值接受参数,则不能在同一个类中声明移动赋值(由于模糊的重载,任何移动赋值都不会编译)。
PS修复作业的关键思想来自这个相关的答案 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.