c – 在向量上使用is_copy_constructible时出现误报
作者:互联网
类型特征是否应该能够处理诸如std :: vector<之类的情况. std :: unique_ptr< int> >并检测到它不是可复制的构造?
这是https://ideone.com/gbcRUa的一个例子(运行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的正确行为,是否有办法检测复制结构是否形成错误?好吧,除了让它无法编译之外.
解决方法:
这是因为std :: vector的设计存在缺陷. std :: vector定义了复制构造,即使它将无法编译,并依赖于std :: vector的用户,如果它将无法编译,则不会调用该方法.
如果向量中包含的类型没有复制构造函数,则替代设计将是SFINAE阻止方法的调用.然而,std :: vector是在现代SFINAE技术发展之前设计的.
它可能会被复制到C的新迭代中,因为会有很少的代码会破坏.人们不能说没有代码会破坏,因为你可以拥有依赖于std :: is_copy_constructible<的std ::矢量< no_copy_type> >是std :: true_type,或等效的表达式,但这是一个非常奇怪的依赖.
除了可以解决这个问题的std :: vector比SFINAE技术更老的事实之外,使用SFINAE这样做是非常混乱的(因为SFINAE是一种混乱的技术).为C 1y提出的新概念-lite可能会使它更清晰,并且更容易被包含在语言的新迭代中.
当我有一个容器需要知道所包含的对象是否可以被安全地复制,比较和排序时,我的工作是专门针对自定义traits类上的std :: vector,并回退到自定义traits类的值上.包含的类型.这是一个拼凑的解决方案,非常具有侵入性.
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容器测试和特征并提取底层值类型并将问题发送给测试关于价值类型. 但根据我的经验,我最终会在std :: vector上进行这些测试. 请注意,由于c++11向量已添加“参与重载决策”规则,因此whixh是标准 – 代表“执行SFINAE”测试.
标签:g4-8,c,c11,typetraits,c++11 来源: https://codeday.me/bug/20190923/1813882.html