我一直在玩,auto我注意到在大多数情况下你可以用一个变量定义替换auto,然后分配类型.
在下面的代码w和x都相等(默认情况下初始化int,还是让我们无法进入潜在副本).有没有办法声明z它具有相同的类型y?
int w{};
auto x = int{};
int y[5];
auto z = int[5];
Run Code Online (Sandbox Code Playgroud)
bam*_*s53 30
template<typename T, int N> using raw_array = T[N];
auto &&z = raw_array<int,5>{};
Run Code Online (Sandbox Code Playgroud)
您的示例auto z = int[5];不仅仅是合法的auto z = int;,仅仅因为类型不是有效的初始值设定项.你可以写:auto z = int{};因为int{}是一个有效的初始化程序.
一旦意识到这一点,下一次尝试将是:
auto z = int[5]{};
Run Code Online (Sandbox Code Playgroud)
请注意,您int y[5]没有任何初始化程序.如果有,那么你会直接跳到这里.
不幸的是,由于语法模糊,这不起作用.相反,您必须找到一种合法的方法来在初始化程序中命名数组类型.例如,typedef名称可以在初始化程序中使用.一个方便的可重用模板类型别名消除了每种数组类型的新typedef的繁琐要求:
template<typename T, int N> using raw_array = T[N];
auto z = raw_array<int,5>{};
Run Code Online (Sandbox Code Playgroud)
旁白:您可以使用模板类型别名来修复C++的奇怪"由内而外"的语法,允许您使用此提议以有序,从左到右的方式命名任何复合类型.
不幸的是由于在C和C++这导致阵列到指针转换在动不动的设计错误,推导的变量类型z是int*相当int[5].当临时数组被销毁时,结果变量成为悬空指针.
C++ 14介绍decltype(auto)了使用不同类型的演绎规则,正确推导出一种数组类型:
decltype(auto) z = raw_array<int,5>{};
Run Code Online (Sandbox Code Playgroud)
但现在我们遇到了另一个数组设计错误; 它们不像正确的物体那样.您不能使用数组分配,复制构造,按值传递等.上面的代码就像是说:
int g[5] = {};
int h[5] = g;
Run Code Online (Sandbox Code Playgroud)
通过所有权利,这应该工作,但不幸的是,内置数组在C和C++中表现得奇怪.在我们的例子中,具体问题是不允许数组只有任何类型的初始化器; 它们严格限于使用初始化列表.由初始化列表初始化的数组临时本身不是初始化列表.
在这一点上,Johannes Schaub提出了一个很好的建议,即我们可以使用临时终身扩展.
auto &&z = raw_array<int,5>{};
Run Code Online (Sandbox Code Playgroud)
decltype(auto)不需要因为添加&&了推断类型的更改,所以Johannes Schaub的建议适用于C++ 11.这也避免了对数组初始值设定项的限制,因为我们正在初始化引用而不是数组.
如果希望数组从初始化程序中推导出它的长度,则可以使用不完整的数组类型:
template<typename T> using unsized_raw_array = T[];
auto &&z = unsized_raw_array<int>{1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
虽然上面做了你想要的,你可能更愿意完全避免原始数组,因为原始数组的行为不像正确的C++对象,以及它们的行为模糊和上面使用的技术.
std::arrayC++ 11中的模板确实像一个正确的对象,包括赋值,可以通过值等等,并且通常只有内置数组才能保持一致和一致.
auto z = std::array<int,5>{};
Run Code Online (Sandbox Code Playgroud)
然而,有了这个,你错过了能够让数组类型从初始化器推断自己的长度.相反,您可以编写一个make_array执行推理的模板函数.这是一个非常简单的版本,我没有测试过,也没有做你想做的事情,例如验证所有参数是相同的类型,还是让你明确指定类型.
template<typename... T>
std::array<typename std::common_type<T...>::type, sizeof...(T)>
make_array(T &&...t) {
return {std::forward<T>(t)...};
}
auto z = make_array(1,2,3,4,5);
Run Code Online (Sandbox Code Playgroud)
不太一样,但你可以使用array:
auto z = std::array<int, 5>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17638 次 |
| 最近记录: |