Skip to content

Commit

Permalink
完成第一版的 LaTex 现代C++题目。
Browse files Browse the repository at this point in the history
  • Loading branch information
Mq-b committed Nov 9, 2023
1 parent da1b717 commit c3721ab
Show file tree
Hide file tree
Showing 15 changed files with 538 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,8 @@ auto v2 = make_vector(std::vector{1,2,3}); // std::vector<int>
## `13` 关于 `return std::move`
日期:`2023/9/6` 出题人:`mq白`
我们会给出三段使用到了 `return std::move` 代码。
**解释说明这些代码是否有问题,问题在哪,或者没问题,那么为什么要这样使用。**
Expand Down
Binary file added src/PDF版题目与答案/image/06_atomic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/PDF版题目与答案/tex/question03.tex
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@
\end{minted}

\begin{tcolorbox}[title = {要求运行结果},
fonttitle = \bfseries, fontupper = \sffamily, fontlower = \itshape]
fonttitle = \bfseries, fontupper = \sffamily, fontlower = \itshape]
1/10
\end{tcolorbox}

\begin{itemize}
\item \textbf{难度}: \hardscore{3} \\
\textbf{提示}:std::formatter。
\textbf{提示}:std::formatter。
\end{itemize}

禁止面向结果编程,使用宏等等方式,本题主要考察和学习 format 库,记得测试至少三个不同编译器。
53 changes: 53 additions & 0 deletions src/PDF版题目与答案/tex/question04.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
日期:2023/7/25 出题人:\href{ https://b23.tv/FM0evat}{Maxy}\\

\begin{minted}[mathescape,
linenos,
numbersep=5pt,
gobble=2,
frame=lines,
framesep=2mm]{c++}
#include<iostream>
class ComponentBase{
protected:
static inline size_t component_type_count = 0;
};
template<typename T>
class Component : public ComponentBase{
public:
//todo...
//使用任意方式更改当前模板类,使得对于任意类型X,若其继承自Component

//则X::component_type_id()会得到一个独一无二的size_t类型的id(对于不同的X类型返回的值应不同)
//要求:不能使用std::type_info(禁用typeid关键字),所有id从0开始连续。
};
class A : public Component<A>
{};
class B : public Component<B>
{};
class C : public Component<C>
{};
int main()
{
std::cout << A::component_type_id() << std::endl;
std::cout << B::component_type_id() << std::endl;
std::cout << B::component_type_id() << std::endl;
std::cout << A::component_type_id() << std::endl;
std::cout << A::component_type_id() << std::endl;
std::cout << C::component_type_id() << std::endl;
}
\end{minted}

\begin{tcolorbox}[title = {要求运行结果},
fonttitle = \bfseries, fontupper = \sffamily, fontlower = \itshape]
0\\
1\\
1\\
0\\
0\\
2
\end{tcolorbox}

\begin{itemize}
\item \textbf{难度}: \hardscore{1} \\
\textbf{提示}:初始化。
\end{itemize}
86 changes: 86 additions & 0 deletions src/PDF版题目与答案/tex/question05.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
日期:2023/7/29 出题人:\href{https://github.com/dynilath}{Da'Inihlus}\\

要求实现 \textbf{scope\_guard} 类型(即支持传入任意可调用类型 , 析构的时候同时调用 )。

\begin{minted}[mathescape,
linenos,
numbersep=5pt,
gobble=2,
frame=lines,
framesep=2mm]{c++}
#include <cstdio>
#include <cassert>

#include <stdexcept>
#include <iostream>
#include <functional>

struct X {
X() { puts("X()"); }
X(const X&) { puts("X(const X&)"); }
X(X&&) noexcept { puts("X(X&&)"); }
~X() { puts("~X()"); }
};

int main() {
{
// scope_guard的作用之一,是让各种C风格指针接口作为局部变量时也能得到RAII支持
// 这也是本题的基础要求
FILE * fp = nullptr;
try{
fp = fopen("test.txt","a");
auto guard = scope_guard([&] {
fclose(fp);
fp = nullptr;
});

throw std::runtime_error{"Test"};
} catch(std::exception & e){
puts(e.what());
}
assert(fp == nullptr);
}
puts("----------");
{
// 附加要求1,支持函数对象调用
struct Test {
void operator()(X* x) {
delete x;
}
} t;
auto x = new X{};
auto guard = scope_guard(t, x);
}
puts("----------");
{
// 附加要求2,支持成员函数和std::ref
auto x = new X{};
{
struct Test {
void f(X*& px) {
delete px;
px = nullptr;
}
} t;
auto guard = scope_guard{&Test::f, &t, std::ref(x)};
}
assert(x == nullptr);
}
}
\end{minted}

\begin{tcolorbox}[title = {要求运行结果},
fonttitle = \bfseries, fontupper = \sffamily, fontlower = \itshape]
Test \\
---------- \\
X() \\
~X() \\
---------- \\
X() \\
~X()
\end{tcolorbox}

\begin{itemize}
\item \textbf{难度}: \hardscore{4} \\
\textbf{提示}:C++11 形参包,成员指针,完美转发,std::tuple,std::apply,C++17 类推导指引,std::invoke,std::function
\end{itemize}
28 changes: 28 additions & 0 deletions src/PDF版题目与答案/tex/question06.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
日期:2023/8/2 出题人:mq白

\begin{minted}[mathescape,
linenos,
numbersep=5pt,
gobble=2,
frame=lines,
framesep=2mm]{c++}
#include <iostream>
#include <atomic>
int main() {
std::atomic<int> n = 6;
std::cout << n << '\n';
}
\end{minted}

详细解释,为什么以上代码在 C++17 后可以通过编译, C++17 前不行?

\begin{figure}[H]
\caption{不同编译器的 C++17 与 C++14 对比}
\centering
\includegraphics[width = 1.0\textwidth]{image/06_atomic.png}
\end{figure}

\begin{itemize}
\item \textbf{难度}: \hardscore{3} \\
\textbf{提示}:复制消除。
\end{itemize}
39 changes: 39 additions & 0 deletions src/PDF版题目与答案/tex/question07.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
日期:2023/8/6 出题人:mq白\\

给出代码:

\begin{minted}[mathescape,
linenos,
numbersep=5pt,
gobble=2,
frame=lines,
framesep=2mm]{c++}
struct MyException :std::exception {
const char* data{};
MyException(const char* s) :data(s) { puts("MyException()"); }
~MyException() { puts("~MyException()"); }
const char* what()const noexcept { return data; }
};
void f2() {
throw new MyException("new Exception异常....");
}
int main(){
f2();
}
\end{minted}

灵感来源自 Java 人写 C++。

在 main 函数中自行修改代码,接取 f2() 函数抛出的异常(try catch)。

\begin{tcolorbox}[title = {要求运行结果},
fonttitle = \bfseries, fontupper = \sffamily, fontlower = \itshape]
MyException()\\
new Exception异常....\\
~MyException()
\end{tcolorbox}

\begin{itemize}
\item \textbf{难度}: \hardscore{1} \\
\textbf{提示}:std::exception,try catch
\end{itemize}
35 changes: 35 additions & 0 deletions src/PDF版题目与答案/tex/question08.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
日期:2023/8/12 出题人:mq白\\

给出代码:

\begin{minted}[mathescape,
linenos,
numbersep=5pt,
gobble=2,
frame=lines,
framesep=2mm]{c++}
template<class Ty,size_t size>
struct array {
Ty* begin() { return arr; };
Ty* end() { return arr + size; };
Ty arr[size];
};
int main() {
::array arr{1, 2, 3, 4, 5};
for (const auto& i : arr) {
std::cout << i << ' ';
}
}
\end{minted}

要求自定义推导指引,不更改已给出代码,使得代码成功编译并满足运行结果。

\begin{tcolorbox}[title = {要求运行结果},
fonttitle = \bfseries, fontupper = \sffamily, fontlower = \itshape]
1 2 3 4 5
\end{tcolorbox}

\begin{itemize}
\item \textbf{难度}: \hardscore{3} \\
\textbf{提示}:参考 std::array 实现,C++17类模板推导指引
\end{itemize}
46 changes: 46 additions & 0 deletions src/PDF版题目与答案/tex/question09.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
日期:2023/8/15 出题人:mq白

\begin{minted}[mathescape,
linenos,
numbersep=5pt,
gobble=2,
frame=lines,
framesep=2mm]{c++}
#include<iostream>

template<class T>
struct X {
void f()const { std::cout << "X\n"; }
};

void f() { std::cout << "全局\n"; }

template<class T>
struct Y : X<T> {
void t()const {
this->f();
}
void t2()const {
f();
}
};

int main() {
Y<void>y;
y.t();
y.t2();
}
\end{minted}

给出以上代码,要求解释其运行结果。

\begin{tcolorbox}[title = {要求运行结果},
fonttitle = \bfseries, fontupper = \sffamily, fontlower = \itshape]
X\\
全局
\end{tcolorbox}

\begin{itemize}
\item \textbf{难度}: \hardscore{3} \\
\textbf{提示}:名字查找。本问题堪称经典,在某著名 template 书籍也有提过(虽然它完全没有讲清楚)。 并且从浅薄的角度来说,本题也可以让你向其他人证明加 this 访问类成员,和不加,是有很多区别的。
\end{itemize}
37 changes: 37 additions & 0 deletions src/PDF版题目与答案/tex/question10.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
题目的要求非常简单,在很多其他语言里也经常提供这种东西(一般是反射)。 但是显而易见 C++ 没有反射。\\

我们给出代码:

\begin{minted}[mathescape,
linenos,
numbersep=5pt,
gobble=2,
frame=lines,
framesep=2mm]{c++}
int main() {
struct X { std::string s{ " " }; }x;
struct Y { double a{}, b{}, c{}, d{}; }y;
std::cout << size<X>() << '\n';
std::cout << size<Y>() << '\n';

auto print = [](const auto& member) {
std::cout << member << ' ';
};
for_each_member(x, print);
for_each_member(y, print);
}
\end{minted}

要求自行实现 for\_each\_member 以及 size 模板函数。 要求支持任意自定义类类型(聚合体)的数据成员遍历(聚合体中存储数组这种情况不需要处理)。 这需要打表,那么我们的要求是支持聚合体拥有 0 到 4 个数据成员的遍历。

\begin{tcolorbox}[title = {要求运行结果},
fonttitle = \bfseries, fontupper = \sffamily, fontlower = \itshape]
1 \\
4 \\
0 0 0 0 %此处效果有问题,使用 tcolorbox 包没有办法显示前空格,除非全部重写
\end{tcolorbox}

\begin{itemize}
\item \textbf{难度}: \hardscore{4} \\
\textbf{提示}:\href{https://akrzemi1.wordpress.com/2020/10/01/reflection-for-aggregates/}{学习},boost::pfr。
\end{itemize}
27 changes: 27 additions & 0 deletions src/PDF版题目与答案/tex/question11.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
日期:2023/8/20 出题人:\href{https://github.com/rsp4jack}{jacky}\\

思考:以下代码为什么在 C++20 以下的版本中无法成功编译,而在 C++20 及以后却可以?

\begin{minted}[mathescape,
linenos,
numbersep=5pt,
gobble=2,
frame=lines,
framesep=2mm]{c++}
#include <vector>

struct Pos {
int x;
int y;
};

int main(){
std::vector<Pos> vec;
vec.emplace_back(1, 5);
}
\end{minted}

\begin{itemize}
\item \textbf{难度}: \hardscore{2} \\
\textbf{提示}:new,聚合初始化。
\end{itemize}
Loading

0 comments on commit c3721ab

Please sign in to comment.