对于仅限iPad的应用程序或通用应用程序,该"Requires full screen"
选项告诉Xcode/iOS该应用程序是否支持iOS 9中引入的iPad多任务处理功能.但"Requires full screen"
如果它是仅限iPhone的应用程序,则该选项也会出现.在这种情况下,这个选项有什么影响?
今天我通过了这个问题:C++ 11中COW std :: string实现的合法性
该问题的最多投票答案(35票赞成)说:
这是不允许的,因为根据标准21.4.1 p6,只允许迭代器/引用的失效
- 作为任何标准库函数的参数,将非const basic_string作为参数引用.
- 调用非const成员函数,除了operator [],at,front,back,begin,rbegin,end和rend.
对于COW字符串,调用非const运算符[]将需要复制(并使引用无效),上面的段落不允许这样做.因此,在C++ 11中拥有COW字符串已不再合法.
我想知道这种理由是否有效,因为C++ 03似乎对字符串迭代器失效有类似的要求:
引用basic_string序列元素的引用,指针和迭代器可能会被该basic_string对象的以下用法无效:
- 作为非成员函数的参数swap()(21.3.7.8),operator >>()(21.3.7.9)和getline()(21.3.7.9).
- 作为basic_string :: swap()的参数.
- 调用data()和c_str()成员函数.
- 调用非const成员函数,除了operator [](),at(),begin(),rbegin(),end()和rend().
- 除了返回迭代器的insert()和erase()形式之外的任何上述用法之后,第一次调用非const成员函数operator [](),at(),begin(),rbegin(),end ()或rend().
这些与C++ 11的不完全相同,但至少operator[]()
在原始答案作为主要理由的部分是相同的.所以我想,为了证明C++ 11中COW std :: string实现的非法性,需要引用其他一些标准要求.需要帮助.
这个SO问题已经停止了一年多,所以我决定将其作为一个单独的问题提出来.如果这不合适,请告诉我,我会找到其他方法来澄清我的疑问.
查看标准中普通默认构造函数的定义:
如果默认构造函数不是用户提供的,则默认构造函数是微不足道的,如果:
- 它的类没有虚函数(10.3),也没有虚基类(10.1),和
- 没有类的非静态数据成员有一个大括号或等于初始化器,和
- 它的所有直接基类都有简单的默认构造函数,和
- 对于类类的所有非静态数据成员(或其数组),每个这样的类都有一个普通的默认构造函数.
否则,默认构造函数是非平凡的.
似乎默认构造函数的平凡性的定义并不排除deleted
默认构造函数的可能性:
struct A {
int& a; // the implicitly defaulted default constructor will be defined as deleted
};
struct B {
B()=delete; // explicitly deleted
};
int main() {
static_assert(is_trivial<A>::value, "");
static_assert(is_trivial<B>::value, "");
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在没有任何断言失败的情况下运行.该类型具有普通的默认构造函数,并且可以轻松复制,因此它是一个"trivial class"
.
不会让这种类型"trivial class"
带来麻烦吗?例如,对象生命周期,字节副本等效,goto
语句允许等.
编辑:以下goto allowance示例无效.感谢@ Casey的评论.添加了另一个逐字节副本等效的示例来替换这个.
以goto
声明津贴为例,标准说:
可以转换为块,但不能以初始化绕过声明的方式.从具有自动存储持续时间的变量不在范围内的点跳转到其在范围内的点的程序是不正确的,除非该变量具有标量类型,具有普通默认构造函数的类类型和普通的析构函数,这些类型之一的cv限定版本,或者前面类型之一的数组,并且在没有初始值设定项的情况下声明(8.5).
所以对于以下代码:
class A {
int& a;
public:
A(int& aa): a{aa} {}
A()=default; // this is necessary otherwise no default constructor …
Run Code Online (Sandbox Code Playgroud) 这实际上是关于界面设计的一般性问题,但我更容易以std::pair
一个例子为例:
template <class T1, class T2>
struct pair {
...
pair(const T1& x, const T2& y);
template<class U, class V> pair(U&& x, V&& y);
...
};
Run Code Online (Sandbox Code Playgroud)
所以我们可以看到有两个重载都需要2个参数来初始化该对的2个成员.我的问题是,提供第一个有什么好处,而第二个可用?是否有任何类型的参数只能传递给第一个而不是第二个?
(让我们暂时搁置标准库的向后兼容性考虑,并讨论接口设计作为一般性问题.)
请考虑以下代码:
class A {
public:
int i;
A() {}
};
class B {
public:
A a;
int i;
};
int main() {
B* p = new B {};
std::cout << p->i << " " << p->a.i << "\n";
}
Run Code Online (Sandbox Code Playgroud)
在clang ++中用-std = c ++ 11编译,p->i
结果为零,但p->a.i
没有.只要它的类没有用户提供的构造函数,整个对象是否应该归零?
编辑:由于评论中有一些广泛的讨论,我认为最好从标准中添加一些摘录:
对值初始化类型的对象
T
意味着:
- 如果
T
是具有用户提供的构造函数(12.1)的(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T
没有可访问的默认构造函数,则初始化是错误的);- 如果
T
是没有用户提供的构造函数的(可能是cv限定的)非联合类类型,则该对象是零初始化的,如果T
隐式声明的默认构造函数是非平凡的,则调用该构造函数.- 如果
T
是数组类型,则每个元素都是值初始化的;- 否则,该对象被零初始化.
零初始化T类型的对象或引用意味着:
- 如果
T
是标量类型(3.9),则将对象设置为值0
(零),作为整数常量表达式,转换为T
;- 如果
T
是(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;- if
T …
当iOS应用的Xcode项目是新建的,在项目(非目标)的设置,我们可以看到,它Use Base internationalization
在默认情况下启用,并有2个文件进行了本地化Development Language
这是English
在默认情况下(一个用于Main.storyboard
和一个LaunchScreen.storyboard
,两个它位于Base.lproj
目录中).见下面的截图:
(为简单起见,我只会Main.storyboard
从现在开始提及.)
在Main.storyboard
右侧面板的本地化部分,我们可以看到Base
默认情况下会检查本地化,并且还有一个English
默认情况下未选中的本地化.见下面的截图:
在目标中Info.plist
,有一个名为Localization native development region
(ie CFBundleDevelopmentRegion
)的键,其默认值为en
.见下面的截图:
如果我理解正确,使用这些默认设置,开发人员只需在Base
本地化中编写英语,Main.storyboard
并保持English
本地化未经检查.如果应用程序需要适应其他语言,开发人员可以在项目本地化设置中添加本地化,并Main.storyboard
在弹出的对话框中选择.见下面的截图:
以Chinese (Simplified)
为例,这将导致一个新创建的目录zh-Hans.lproj
与Main.strings
里面的文件.(为简单起见,我将把它作为Chinese
代替Chinese (Simplified)
.)开发者只需要这个文件里面的英文字符串翻译成中国(新创建Main.strings
的zh-Hans.lproj
目录默认拥有所有从重复的英文文本Main.storyboard
中Base.lproj
).通过这些设置,Language
AppStore上此应用程序描述中的字段将列出英语(来自Base
本地化,因为英语是development language
)和中文(来自Chinese
本地化).在最终用户的设备上,如果系统语言是英语/中文(或英语/中文是首选语言),应用程序将使用相应的语言资源(对于英语,使用Base
本地化;对于中文,使用Chinese …
除了支持多个参数,禁止缩小转换,匹配构造函数采用std :: initializer_list参数,复制列表初始化与传统复制初始化有什么不同?
具体而言,假设有两种用户定义的类型,A
并且B
:
class A {...};
class B {...};
B b;
A a1 = {b};
A a2 = b;
Run Code Online (Sandbox Code Playgroud)
对这两种初始化形式有什么样的定义A
并B
会有所作为?例如,是否存在某种定义,A
并且B
会使其中一种初始化合法但另一种是非法的,或者是合法的但具有不同的语义,或者两者都是非法的,具有不同的原因?
(假设A
没有构造函数采用std :: initializer_list参数.)
编辑:添加链接到我的一个有点相关的问题:在具有转换运算符的初始化程序的情况下,复制列表初始化的假设行为是什么?
对于std :: vector的副本分配,当源的大小小于目标的容量时,是否允许重新分配存储和容量缩减?或者是否保证不会发生重新分配/收缩(即始终遵守先前的保留())?
另一方面,如果源的大小大于目的地的容量并且重新分配,则需要重新分配是否与源的容量相关(例如,目的地的新容量应不小于源的容量,或者甚至需要它们是一样的)?或者重新分配只是完成其工作(基于新的大小)而不考虑源的容量?
至于移动分配,我认为不会进行存储重新分配(虽然我未能在标准中找到相关部分),那么它是否意味着目标新容量的值与源的旧容量完全相同?我能期望v = vector<T>{};
产生同样的效果vector<T>{}.swap(v);
吗?
我想答案都隐藏在标准的某个地方,但我却找不到它们.(如果C++ 11和C++ 03的内容不同,我想知道两者的各种要求.)
PS:对于上述问题的答案,对于std :: string是否相同(仅在C++ 11中,这意味着连续存储而且没有COW,C++ 03字符串不在雷达中)?
对于以下代码:
class A {};
template <typename T> void f(T& a) {}
template <typename T> void f(T&& a) {}
int main() {
A a;
f(a);
}
Run Code Online (Sandbox Code Playgroud)
clang ++将调用绑定到第一个重载,而g ++报告模糊调用.哪一个采取了正确的行动?
在C++ 11标准的兼容性附录中,从C++ 03到C++ 11的更改之一描述如下:
C.2.11第21节:字符串库
21.4.1
更改:松开basic_string失效规则
原理:允许小字符串优化.
对原始功能的影响:有效的C++ 2003代码可能在本国际标准中执行不同.某些const成员函数(如data和c_str)不再使迭代器无效.
迭代器失效规则std::string
确实已从C++ 03更改为C++ 11,data()
并且c_str()
不允许再使迭代器失效,但我不知道这是如何导致" allow small-string optimization
" 的基本原理的?在C++ 11之前是否已经允许SSO?
std::string
在我遇到兼容性附录中的SSO注释之前,我所知道的C++ 11和C++ 03之间的两个区别是:
operator[]
不允许使迭代器无效)我采用了C++ 11的非无效保证,c_str()
并将其data()
作为连续存储更改的直接结果.现在似乎与SSO实现存在一些联系,我想知道幕后逻辑的细节.谢谢.