eca*_*mur 16 c++ optional type-traits c++-standard-library c++14
(可能不是C++ 14,可能是库TS)工具make_optional被定义为(在n3672中):
template <class T>
constexpr optional<typename decay<T>::type> make_optional(T&& v) {
return optional<typename decay<T>::type>(std::forward<T>(v));
}
Run Code Online (Sandbox Code Playgroud)
为什么有必要改变类型T(即不仅仅是返回optional<T>),是否有一种哲学(以及实际)理由用于decay转换?
Yak*_*ont 16
一般目的decay是采取类型并将其修改为适合存储.
看一下这些可以decay实现工作的例子,而remove_reference不是:
auto foo( std::string const& s ) {
if (global_condition)
return make_optional( s );
else
return {};
}
Run Code Online (Sandbox Code Playgroud)
要么
void function() { std::cout << "hello world!\n"; }
auto bar() { return std::make_optional( function ); }
Run Code Online (Sandbox Code Playgroud)
要么
int buff[15];
auto baz() { return std::make_optional( buff ); }
Run Code Online (Sandbox Code Playgroud)
一个optional<int[15]>将是一个非常奇怪的野兽-当像文字,这是治疗的空调风格阵列不守规矩optional确实给它的参数T.
如果你正在数据的副本中,const或volatile源的性质并不重要.而且你只能通过将它们衰减为指针来制作数组和函数的简单副本(不会丢失std::array或类似).(理论上,可以做一些optional<int[15]>工作来完成工作,但这会带来许多额外的复杂因素)
所以std::decay解决所有这些问题,并不会真正导致问题,只要你允许make_optional推断其参数的类型而不是T字面上的传递.
如果你想传入T字面意思,make_optional毕竟没有理由使用.
Bri*_*ian 14
这不是新行为make_optional; 实用程序的功能make_pair和make_tuple行为方式相同.我至少可以看到两个理由:
实际上用未解析的类型实例化模板可能是不合需要的或不可能的.
如果T是一个函数类型,那么,你就是不能在一个类中存储一个函数,句点; 但你可以存储一个函数指针(衰减类型).
如果T是数组类型:由于数组不可复制,因此无法复制生成的类"有缺陷".对于optional该value_or成员函数不能在所有被编译,因为它返回T.因此,您根本无法拥有数组类型optional.
不衰减类型可能会导致意外行为.
如果参数是字符串文字,我个人希望包含的类型const char*不是const char [n].这种衰变发生在大多数地方,为什么不在这里呢?
如果v是左值,T则将推导为左值引用类型.我是否真的想要一个包含引用的对,例如,因为其中一个参数是左值?当然不是.
对或元组内的类型或可选或任何不应获得cv资格的类型v.也就是说,我们已经x宣布为const int.应该make_optional(x)创造一个optional<const int>?不,不应该; 它应该创造optional<int>.
看看它做了什么decay:
删除引用限定符 - T&→ T; 没有可选引用,否则你无法重置optional,需要分配.
对于数组类型,删除extent- T[42]→ T*; 可选的固定范围数组没有用,因为每个数组大小都有不同的类型,并且您不能按值直接传递数组类型,这对于value和value_or成员函数来说是必需的.
对于函数类型,添加指针 - T(U)→ T(*)(U); 由于类似的原因,没有可选的函数引用.
否则,删除cv-qualifiers- const int→ int; 没有可选const值,否则你无法重置optional.
| 归档时间: |
|
| 查看次数: |
1825 次 |
| 最近记录: |