为什么 is_copy_constructible return 在 MSVC12 中对 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 编译:
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x64
static_assert
应该触发,std::unique_ptr has an implicitly deleted copy constructor, so this is a bug. This looks related to this bug report std::is_copy_constructible is broken:
(1) std::is_copy_constructible returns true for types with deleted
copy constructors.
(2) std::is_copy_constructible returns true for types that compose
types that are not copy constructible.
响应是:
Thanks for reporting this bug. We've fixed it, and the fix will be available in the next major version of Visual Studio after 2013.
另请参阅此错误报告:std::is_copy_constructible doesn't work correctly。
请注意,断言在 webcompiler which is using an up to date version of Visual Studio. The last update was on Dec 3, 2015
. The assert also fires on clang(see it live) 和 gcc.
上触发
我发现了一个错误报告:A strange behavior of std::is_copy_constructible,它与您的代码非常相似:
static_assert(std::is_copy_constructible<std::unique_ptr<int>>::value, "");
那里的回应是:
Thanks for reporting this bug. We've already fixed it, and the fix is
available in VS 2015 Preview.
不清楚,Visual Studio 哪个版本修复了这个问题。一个回复说是 2013 年末版本,而后一个回复说是 2015 预览版。
这里有四种制作方法 class non-copyable:
#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 (18.00.40629 for x64
) 上,它打印:
1 1 //A
0 1 //B
1 0 //C
0 0 //D
在正确的编译器上,所有八个值都必须为零。
不幸的是,这 不是 提供解决 MSVC2013 中错误的好方法,即使对于您自己的 classes 也是如此。因为如果你声明赋值运算符按值接受参数,那么你不能在同一个class中声明移动赋值(任何移动赋值都不会编译,因为有歧义的重载)。
P.S. 固定分配的关键思想取自 this related answer.
我原以为这个静态断言会触发:
#include <type_traits>
#include <memory>
int main() {
static_assert(std::is_copy_constructible<std::unique_ptr<int>>::value, "UPtr has copy constructor?");
}
但事实并非如此。
使用 MSVC12 编译:
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x64
static_assert
应该触发,std::unique_ptr has an implicitly deleted copy constructor, so this is a bug. This looks related to this bug report std::is_copy_constructible is broken:
(1) std::is_copy_constructible returns true for types with deleted copy constructors.
(2) std::is_copy_constructible returns true for types that compose types that are not copy constructible.
响应是:
Thanks for reporting this bug. We've fixed it, and the fix will be available in the next major version of Visual Studio after 2013.
另请参阅此错误报告:std::is_copy_constructible doesn't work correctly。
请注意,断言在 webcompiler which is using an up to date version of Visual Studio. The last update was on Dec 3, 2015
. The assert also fires on clang(see it live) 和 gcc.
我发现了一个错误报告:A strange behavior of std::is_copy_constructible,它与您的代码非常相似:
static_assert(std::is_copy_constructible<std::unique_ptr<int>>::value, "");
那里的回应是:
Thanks for reporting this bug. We've already fixed it, and the fix is available in VS 2015 Preview.
不清楚,Visual Studio 哪个版本修复了这个问题。一个回复说是 2013 年末版本,而后一个回复说是 2015 预览版。
这里有四种制作方法 class non-copyable:
#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 (18.00.40629 for x64
) 上,它打印:
1 1 //A
0 1 //B
1 0 //C
0 0 //D
在正确的编译器上,所有八个值都必须为零。
不幸的是,这 不是 提供解决 MSVC2013 中错误的好方法,即使对于您自己的 classes 也是如此。因为如果你声明赋值运算符按值接受参数,那么你不能在同一个class中声明移动赋值(任何移动赋值都不会编译,因为有歧义的重载)。
P.S. 固定分配的关键思想取自 this related answer.