CppQuiz is a simple online quiz that you can use to test your knowledge of the C++ programming language.

According to the C++11 standard, what is the output of this program?

### Q2

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration

### Q3

The type of a floating literal is double unless explicitly specified by a suffx. The suffxes f and F specify float, the suffxes l and L specify long double.

double转换到internal需要按照Integer conversion rank，具体请看**[ISO/IEC 14882:2014 4.13]**

The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.

### Q6

**Answare: **012012

### Q11

According to the C++11 standard, what is the output of this program?

[ISO/IEC 14882:2014 §8.5/10]Every object of static storage duration is zero-initialized at program startup before any other initialization takes place.

### Q13

It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main.

### Q15

1. 首先，调用foo()foo函数体中创建了一个static B对象，因为没有提供初始化式，所以会调用B的默认构造函数。
2. 根据对象构造时的执行顺序，来初始化基类(如果有的话)和数据成员。因为类B没有基类且只有一个A类的数据成员a，按照上面的规则，会先执行成员a的初始化，因为也没有提供初始化式，所以也会调用A的默认构造函数。
3. A的默认构造函数中输出a，然后检查此时x++ == 0的结果为true，所以会在A的构造函数中抛出一个异常。因为当在构造函数抛出一个异常时，会对其所有完全构造的子对象(不包括类似union的类的变体成员)执行构造函数，因此，A中并没有任何数据成员，所以会直接结束类A的构造，不会执行任何析构函数。
4. catch中捕获到异常，并输出一个c
5. 再次执行foo()，然后依次执行B->A的构造，先调用B中数据成员a的的构造函数。(输出a)，由于上面执行过了x++，所以此时x++==0位false，不会抛出异常，A的对象构造成功。
6. 执行B的构造函数体，输出b
7. 程序结束时开始析构B类对象b，根据对象析构时的执行顺序来执行(和构造反序)
8. 根据上面的规则，会先调用b的析构函数输出B
9. 然后再调用b的A类数据成员a的析构函数输出A

### Q17

where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.

After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X’s direct non-variant non-static data members, the destructors for X’s direct base classes and, if X is the type of the most derived class (12.6.2), its destructor calls the destructors for X’s virtual base classes. All destructors are called as if they were referenced with a qualified name, that is, ignoring any possible virtual overriding destructors in more derived classes. Bases and members are destroyed in the reverse order of the completion of their constructor (see 12.6.2). A return statement (6.6.3) in a destructor might not directly return to the caller; before transferring control to the caller, the destructors for the members and bases are called. Destructors for elements of an array are called in reverse order of their construction (see 12.6).

### Q25

**Answare: **The programm is undefined.

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.[ Note: most existing implementations of C++ ignore integer overﬂows. Treatment of division by zero, forming a remainder using a zero divisor, and all ﬂoating point exceptions vary among machines, and is usually adjustable by a library function. — end note ]

### Q27

**Answare: **B

The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its bases and members.

**Answare: **121

### Q32

The first line in main(), X x; is straightforward, it calls the default constructor.
The next two lines is the heart of the question: The difference between X y(x) and X z = y is not that the first calls the copy constructor, and the second calls the copy assignment operator. The difference is that the first is direct initialization (§8.5.15 in the standard) and the second is copy initialization (§8.5.14).
§8.5.16 says: “If the initialization is direct-initialization, or if it is copy-initialization where the (…) source type is the same class as (…) the class of the destination, constructors are considered.” So both our cases use the copy constructor.
Not until z = x; do we have an actual assignment that uses the assignment operator.
See http://stackoverflow.com/#1051468 for a more detailed discussion of direct vs. copy initialization.

### Q35

v1是一个元素被初始化为2，可以看下vector的构造函数：

v2是用一个初始化列表(initializer_list)来初始化vector对象，结果是初始化列表中的元素的个数。

### Q112

B b1;的构造顺序为1.扩充B的构造函数，将A的构造函数来构造成员对象a；2.调用B的默认构造函数。

First, b1 is default initialized. All members are initialized before the body of the constructor, so b1.a is default initialized first, and we get the output 14.
§12.6.2¶8 in the standard: “In a non-delegating constructor, if a given non-static data member or base class is not designated by a
mem-initializer-id (…) then if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initialized as specified in §8.5 (…) otherwise, the entity is default-initialized.”
Then, b2 is initialized with the move construcor (since std::move(b1)converts the reference to b1 to an xvalue, allowing it to be moved from.) In B’s move constructor, a is initialized in the initializer list. Even though a is an rvalue reference (and bound to an rvalue), a itself is an lvalue, and cannot be moved from. b2.a is then copy initialized, printing 2, and finally the body of B’s move constructor prints 6.(If the concept of rvalue references being lvalues is confusing, read The Article. Search for “In widget”.)

### Q116

The T&& in the the templated functions do not necessarily denote an rvalue reference, it depends on the type that is used to instantiate the template. If instantiated with an lvalue, it collapses to an lvalue reference, if instantiated with an rvalue, it collapses to an rvalue reference. See note [1].
Scott Meyers has written a very good article about this, where he introduces the concept of “universal references” (note that this is not C++ standard wording) http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
In this example, all three functions are called once with an lvalue and once with an rvalue. In all cases, calling with an lvalue (i) collapses T&& x to T& x (an lvalue reference), and calling with an rvalue (20) collapses T&& x to T&& x (an rvalue reference). Inside the functions, x itself is always an lvalue, no matter if its type is an rvalue reference or an lvalue reference.

• For the first example, y(int&) is called for both cases. Output: 11.
• For the second example, move(x) obtains an rvalue reference, and y(int&&)is called for both cases. Output: 22.
• For the third example, forward(x) obtains an lvalue reference when x is an lvalue reference, and an rvalue reference when x is an rvalue reference, resulting in first a call to y(int&)and then a call to y(int&&). Output: 12.

Note [1]: §8.3.2¶6 in the standard: “If a (…) type template-parameter (§14.3.1) (…) denotes a type TR that is a reference to a type T, an attempt to create the type “lvalue reference to cv TR” creates the type
“lvalue reference to T”, while an attempt to create the type “rvalue reference to cv TR” creates the type TR.” The example at the end of that paragraph is is worth a look.
Note from the contributor: This demonstrates Scott Meyers’s advice that use std::forward for universal references, and std::move for rvalue references.

### Q119

The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below.

Here the second x is initialized with its own (indeterminate) value.

[ISO/IEC 14882:2014 §4.12]A zero value, null pointer value, or null member pointer value is converted to false;any other value is converted to true.

ne: yields true if the operands are unequal, false otherwise. No sign interpretation is necessary or performed.

### Q120

C++运算符的优先级可以在看这篇文章：C++关键字与运算符优先级别速查表

### Q124

A template-parameter of a template template-parameter is permitted to have a default template-argument.When such default arguments are specified, they apply to the template template-parameter in the scope of the template template-parameter.

### Q130

When looking for the declaration of a name used in a template definition, the usual lookup rules (3.4.1,3.4.2) are used for non-dependent names. The lookup of names dependent on the template parameters is postponed until the actual template argument is known (14.6.2).

### Q131

An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax (8.5) or where casts (5.2.9, 5.4) are explicitly used. A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization or value- initialization (8.5).

A constructor declared without the function-specifier explicit specifies a conversion from the types of its parameters to the type of its class. Such a constructor is called a converting constructor.

C c1(7)是直接初始化(direct-initializtion)，而C c2=7;是拷贝初始化(copy-initializatio)。虽然大多数情况下实现应该是等价的，但是在上面的代码中是不一样的。

as well as in new expressions (5.3.4), static_cast expressions (5.2.9), functional notation type conversions (5.2.3), and base and member initializers (12.6.2) is called direct-initialization.

as well as in argument passing, function return, throwing an exception (15.1), handling an exception(15.3), and aggregate member initialization (8.5.1) is called copy-initialization. [ Note: Copy-initialization may invoke a move (12.8). — end note ]

### Q133

**Answare: **ABCDABCd

### Q135

std::map stores values based on a unique key. The keys for mb are boolean, and 13and 5 all evaluate to the same key, true.
§23.4.4.1¶1 in the standard:
“A map is an associative container that supports unique keys (contains at most one of each key value).”
The type of mb is map. The key is bool, so the integers 13 and 5 used for initialization are first converted to bool, and they all evaluate to true.
§4.12¶1 in the standard:
“A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.”

*Answare: **001

### Q144

std::numeric_limits<T>::digits的结果为T的数据位大小(sizeof(T)*CHAR_BIT，不包含符号位)。

bool 布尔类型 未定义
char 字符 8位
wchar_t 宽字符 16位
char16_t Unicode字符 16位
char32_t Unicode字符 32位
short 短整型 16位
int 整型 16位
long 长整型 32位
long long 长整型 64位
float 单精度浮点型 6位有效数字
double 双精度浮点型 10位有效数字
long double 扩展精度浮点型 10位有效数字

else的部分就不多说了，主要是看if范围内的部分。

-0xffffffff=$2^n-\sum_{x=0}^{31}2^i$=1

As the else part of the branch is obvious, we concentrate on the if part and make the assumptions present in the condition.
§2.14.2 in the standard: “The type of an integer literal is the first of the corresponding list in Table 6.” [Table 6: int, unsigned int, long int, unsigned long int … for hexadecimal literals –end Table] in which its value can be represented.”
Since the literal 0xffffffff needs 32 digits, it can be represented as an unsigned int,but not as a signed int, and is of type unsigned int. But what happens with the negative of an unsigned integer?
§5.3.1 in the standard: “The negative of an unsigned quantity is computed by subtracting its value from 2^n , where n is the number of bits in the promoted operand.” Here n is 32, and we get:
2^32 - 0xffffffff = 4294967296 - 4294967295 = 1
So i is initialised to 1, and N[1] is the only element accessed in the loop. (The second time around the loop, i is 0, which evaluates to false, and the loop terminates.)

### Q147

**Answare: **0

Each instance of a backslash character (\) immediately followed by a new-line character is deleted,
splicing physical source lines to form logical source lines.

### Q151

C++标准中规定，char是unsigned还是signed是由实现定义的，所以这个问题是implementation-define behavior.
. It is implementation-defined whether a char object can hold negative values.

### Q153

A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration.

ISO C++11 does not allow conversion from string literal to ‘char *’.

### Q158

vector<Foo> bar(5)其中bar(5)不是将5传递给Foo的构造函数，是指定vector容器中元素的数目

Since C++11 (§23.3.6.2¶3 in the standard), std::vector has a one parameter constructor
explicit vector( size_type n )
which constructs a vector with n value-initialized elements. Each value-initialization calls the default Foo constructor, resulting in the output aaaaa .
The “trick” is, that before C++11, std::vector had a 2 parameter constructor ( + allocator ), which constructed the container with n copies of the second parameter, which is defaulted to T().So this code before C++11 would output abbbbb, because the call would be equivalent to std::vector bar(5,T()).

### Q157

Answer:This question The program is unspecified / implementation defined.

The result of a typeid expression is an lvalue of static type const std::type_info (18.7.1) and dynamic type const std::type_info or const name where name is an implementation-defined class publicly derived from std::type_info which preserves the behavior described in 18.7.1

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id.

Comparing pointers is defined as follows: Two pointers compare equal if they are both null, both point to the same function, or both represent the same address (3.9.2), otherwise they compare unequal.

so,this is a implementation-define.

### Q159

C++标准规定，函数实参的副作用求值在进入函数之前被排序。

[ISO/IEC 14882:2014 §5.2.3.8] All side eﬀects of argument evaluations are sequenced before the function is entered.

### Q160

**Answare: **B1

A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides.