Loading... # 1 C语言链接 ```cpp #include<iostream> namespace A{ extern "C" int x; }; namespace B{ extern "C" int x; }; int A::x = 0; int main(){ std::cout << B::x; A::x=1; std::cout << B::x; } ``` 答案: ```cpp 01 ``` ## 解析 C语言中没有`namespace`,因此指定了C链接后,`A::x`和`B::x`指代同一个对象。 # 2 模板显式偏特化 ```cpp #include <iostream> template<typename T> T sum(T arg) { return arg; } template<typename T, typename ...Args> T sum(T arg, Args... args) { return arg + sum<T>(args...); } int main() { auto n1 = sum(0.5, 1, 0.5, 1); auto n2 = sum(1, 0.5, 1, 0.5); std::cout << n1 << n2; } ``` 答案: ```cpp 32 ``` ## 解析 第一个递归中`T`一直被指定为double,第二个一直被指定为int。 # 3 函数类型推导中的cv限定&螺旋修饰规则 ```cpp #include <iostream> #include <type_traits> int main() { std::cout << std::is_same_v< void(int), void(const int)>; std::cout << std::is_same_v< void(int*), void(const int*)>; } ``` 答案: ```cpp 01 ``` ## 解析 首先是[函数类型推导](https://zh.cppreference.com/w/cpp/language/function)中,**参数**的**直接cv-限定**会被去除: > The type of a function is determined using the following rules. The type of each parameter (including function parameter packs) is determined from its own decl-specifier-seq and declarator. (...) After producing the list of parameter types, <span style='color:red'>any top-level cv-qualifiers modifying a parameter type are deleted</span> when forming the function type. ![image.png](https://zclll.com/usr/uploads/2022/06/678787478.png) 其次是`const`的[螺旋修饰规则](http://c-faq.com/decl/spiral.anderson.html)告诉我们`const int*`和`int const*`都是指向`const int`的指针(指向`int`的`const`指针是`int* const`),因此`const int*`不会去除`const`,所以是不相同的类型。 # 4 auto作为返回值推导 ```cpp #include <iostream> auto sum(int i) { if (i == 1) return i; else return sum(i-1)+i; } int main() { std::cout << sum(2); } ``` 答案: ```cpp 3 ``` ## 解析 `auto`作为返回值推导时,可以存在多条`return`语句,只要推导结果相同即可。而在`return`语句推导时,只要推导出一处具体的结果,即可用于与别处匹配,因此第二条`return`中的`sum(i-1)`在此处直接作为`int`,检查无矛盾即可。 # 5 类类型的默认访问控制 ```cpp #include <iostream> class A {}; class B { public: int x = 0; }; class C : public A, B {}; struct D : private A, B {}; int main() { C c; c.x = 3; D d; d.x = 3; std::cout << c.x << d.x; } ``` 答案: CE ## 解析 C++中`struct`和`class`一样具有访问控制,`class`中默认成员访问为`private`,默认继承为`private`;`struct`中默认成员访问为`public`,默认继承为`public`。本题中做了显式声明,从声明。 # 6 虚函数默认实参 ```cpp #include <iostream> struct A { virtual void foo (int a = 1) { std::cout << "A" << a; } }; struct B : A { virtual void foo (int a = 2) { std::cout << "B" << a; } }; int main () { A *b = new B; b->foo(); } ``` 答案: ```cpp B1 ``` ## 解析 规则: > A virtual function call (§ 13.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. 具体实践来说,默认实参是在编译期在调用处直接写好的,这很好理解。动态绑定遵循了这一点。 # 7 表达式求值顺序 ```cpp #include <iostream> int main() { int I = 1, J = 1, K = 1; std::cout << (++I || ++J && ++K); std::cout << I << J << K; } ``` 答案: ```cpp 1211 ``` ## 解析 > **6)** 内建[逻辑](https://zh.cppreference.com/w/cpp/language/operator_logical "cpp/language/operator logical")与 (AND) 运算符 **&&** 和内建逻辑或 (OR) 运算符 **||** 的第一(左)操作数的每个值计算和副作用,*按顺序早于*第二(右)操作数的每个值计算和副作用。 > 5) 每个使用内建(非重载)运算符的下列四种表达式的求值中,表达式 `a` 的求值后有一个序列点。**a** **&&** **b** > a **||** **b** > a **?** **b** **:** **c** > a , b # 8 字符串常量 ```cpp #include <iostream> int main() { char* a = const_cast<char*>("Hello"); a[4] = '\0'; std::cout << a; } ``` 答案: UB ## 解析 字符串常量`"Hello"`位于常量区,修改是UB。 # 9 字符串字面量 ```cpp #include <iostream> int main() { std::cout << sizeof(""); } ``` 答案: ```cpp 1 ``` ## 解析 字符串字面量被解释为`char[]`而非`char*`,那么自动添加`'\0'`后大小为1。 # 10 重载决议 ```cpp #include<iostream> template<typename T> void foo(T...) {std::cout << 'A';} template<typename... T> void foo(T...) {std::cout << 'B';} int main(){ foo(1); foo(1,2); } ``` 答案: ```cpp AB ``` ## 解析 这个知识点实在是太过复杂了,可以看[cppreference上的介绍](https://zh.cppreference.com/w/cpp/language/overload_resolution)。当然,更复杂的情况,我们可能要先考虑[偏特化决议](https://zh.cppreference.com/w/cpp/language/partial_specialization),再去进行重载决议。 总的来说,这两种决议都遵循一个原则:最佳匹配如果存在,那么它不能在任何一个参数上比其他重载更不特殊,且至少在一个参数上更加特殊。 至于具体规则……这个世界上真的有人能完全掌握吗?…… © 允许规范转载 打赏 赞赏作者 赞 如果觉得我的文章对你有用,请随意赞赏