在vector< unique_ptr>上具有is_copy_constructible的假阳性 [英] False positive with is_copy_constructible on vector<unique_ptr>
问题描述
类型特征是否应该能够处理诸如 std :: vector< std :: unique_ptr< int> >
并检测到它不是可复制的?
Should the type trait be able to handle cases such as std::vector < std::unique_ptr <int> >
and detect that it's not copy constructible?
以下是 https://ideone.com/gbcRUa (运行g ++ 4.8.1)
Here's an example at https://ideone.com/gbcRUa (running g++ 4.8.1)
#include <type_traits>
#include <vector>
#include <iostream>
#include <memory>
int main()
{
// This prints 1, implying that it's copy constructible, when it's clearly not
std::cout << std::is_copy_constructible< std::vector<std::unique_ptr<int> > >::value << std::endl;
return 0;
}
如果这是 is_copy_constructible的正确行为
,有没有办法检测到副本构造格式不正确?好吧,不仅仅是无法编译。
If this is the correct behavior for is_copy_constructible
, is there a way to detect that the copy construction is ill formed? Well, beyond just having it fail to compile.
推荐答案
这是因为 std :: vector $ c $的设计存在缺陷。 c>。
std :: vector
定义副本构造,即使编译失败,也依赖于 std :: vector
的用户
This is because of a flaw in the design of std::vector
. std::vector
defines copy construction even if it will fail to compile, and relies on users of std::vector
to not invoke the method if it will fail to compile.
另一种设计是,如果<$ c $中包含的类型,则SFINAE阻止该方法的调用。 c> vector 没有副本构造函数。但是, std :: vector
是在现代SFINAE技术开发之前设计的。
The alternative design would be to SFINAE block the invocation of the method if the type contained in the vector
does not have a copy constructor. However, std::vector
was designed before modern SFINAE techniques developed.
可以将其复古地安装到C ++的新迭代,因为几乎没有代码会中断。不能说没有代码会中断,因为您可能有依赖于 std :: is_copy_constructible< std :: vector< no_copy_type> >
是 std :: true_type
或等效表达式,但这是一个非常奇怪的依赖项。
It could possibly be retro fitted into a new iteration of C++, as there would be very little code that would break. One cannot say no code would break, because you could have code that relies on the fact that std::is_copy_constructible< std::vector< no_copy_type > >
is std::true_type
, or equivalent expressions, but that is a pretty strange dependency.
除了 std :: vector
比可以解决此问题的SFINAE技术更老的事实外,使用SFINAE这样做非常麻烦(因为SFINAE是一种凌乱的技术)。为C ++ 1y提出的新的Lite概念可能使其变得更整洁,并且更倾向于将其包含在该语言的新迭代中。
On top of the fact that std::vector
is older than the SFINAE techniques that could solve this problem, doing so with SFINAE is pretty messy (as SFINAE is a messy technique). The new concepts-lite proposed for C++1y may make it cleaner, and more tempting to include in a new iteration of the language.
需要知道所包含的对象是否可以安全地复制,比较和排序的容器专门用于自定义特征类的 std :: vector
,并依赖于自定义特征类在所包含类型上的值。
My work around when I have a container that needs to know if the contained object can be safely copied, compared and ordered is to specialize for std::vector
on a custom traits class, and fall back on the value of the custom traits class on the contained type. This is a patchwork solution, and quite intrusive.
template<template<typename>class test, typename T>
struct smart_test : test<T> {};
template<template<typename>class test, typename T, typename A>
struct smart_test<test, std::vector<T,A>> : smart_test<T> {};
这可以给我们:
template<typename T>
using smart_is_copy_constructible = smart_test< std::is_copy_constructible, T >;
,对于<
和 ==
。当遇到更多应该真正将其属性转发到其数据的容器类型时,我可以添加更多的专业化知识,或者可以编写更高级的SFINAE容器测试和特征并提取底层的值类型并将问题分配给测试
and similar for <
and ==
. I can add more specializations when I run into more container-types that should really forward their properties down to their data, or I could write a fancier SFINAE container-test and traits and extract the underlying value-type and dispatch the question to the test on the value-type.
但是根据我的经验,我最终最终还是在 std :: vector
。
But in my experience, I mostly end up doing these tests on std::vector
.
请注意,由于 c ++ 11 向量已添加参与过载解决方案规则,这是 do SFINAE测试的标准说法。
Note that since c++11 vector has had "participates in overload resolution" rules added to it, which is standards-speak for "do SFINAE" tests.
这篇关于在vector< unique_ptr>上具有is_copy_constructible的假阳性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!