Dav*_*e S 14 c++ type-traits c++11 g++4.8
类型特征是否应该能够处理诸如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;
}
Run Code Online (Sandbox Code Playgroud)
如果这是正确的行为is_copy_constructible
,有没有办法检测复制结构是否形成错误?好吧,除了让它无法编译之外.
Yak*_*ont 14
这是因为设计中存在缺陷std::vector
. std::vector
定义复制构造,即使它将无法编译,并依赖于用户std::vector
如果无法编译则不调用该方法.
如果包含在其中的类型vector
没有复制构造函数,则替代设计将是SFINAE阻止方法的调用.然而,std::vector
是在现代SFINAE技术发展之前设计的.
它可能会被复制到C++的新迭代中,因为会有很少的代码会破坏.不能说没有代码将打破,因为你可以有依赖于一个事实,即代码std::is_copy_constructible< std::vector< no_copy_type > >
是std::true_type
,或等同的表达,但是这是一个非常奇怪的依赖.
std::vector
除了可以解决这个问题的SFINAE技术之前的事实,使用SFINAE这样做是非常混乱的(因为SFINAE是一种混乱的技术).为C++ 1y提出的新概念 - lite可能会使它更清晰,并且更容易包含在语言的新迭代中.
当我有一个容器需要知道所包含的对象是否可以被安全地复制,比较和排序时,我的工作是专注std::vector
于自定义traits类,并回退到包含类型上的自定义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> {};
Run Code Online (Sandbox Code Playgroud)
这给了我们:
template<typename T>
using smart_is_copy_constructible = smart_test< std::is_copy_constructible, T >;
Run Code Online (Sandbox Code Playgroud)
和类似的<
和==
.当我遇到更多的容器类型时,我可以添加更多的特殊化,这些容器类型应该真正将它们的属性转发到他们的数据,或者我可以编写一个更高级的SFINAE容器测试和特征并提取底层值类型并将问题发送给测试关于价值类型.
但根据我的经验,我大部分时间都在进行这些测试std::vector
.
归档时间: |
|
查看次数: |
1265 次 |
最近记录: |