hsf-training / cpluspluscourse Goto Github PK
View Code? Open in Web Editor NEWC++ Course Taught at CERN, from Sebastien Ponce (LHCb)
License: Apache License 2.0
C++ Course Taught at CERN, from Sebastien Ponce (LHCb)
License: Apache License 2.0
@amadio suggest to me again, and I also have thought about that, that we should add more pointers to external resources. We have the occasional link to cppreference and I also linked CppCon talks in a couple of places. But there is so much more material available.
Like:
We should add a few slides or even a tiny chapter at the end with further resources to explore for interested students.
A quick first list of items to cover :
And copy elision will take care of MyVector
...
Maybe we should think about something for the future.
Originally posted by @hageboeck in #103 (comment)
The problem is that all the code we suggest will get optimised. We should come up with something that really improves only with move semantics.
Both tools are mentioned in the exercise on the compilation chain, but we have no slide that mentions what these tools do and why/when they are needed.
There was some confusion on how this
is presented in the OO chapter. We should improve the slide.
Originally posted by @sponce in #79 (comment)
as several exercises say "time ..." without details.
Or maybe it's something to put in the "test" exercise with some explanations in the notes ?
This issue is replicated from the previous gitlab repo
If needed...
\frametitlecpp[17]{<Title>}
as in #61sed
-replace all occurencesWe mention doxygen briefly on slide 14 where we show:
// simple comment for integer declaration
int i;
/* multiline comment
* in case we need to say more
*/
double d;
/**
* Best choice : doxygen compatible comments
* \brief checks whether i is odd
* \param i input
* \return true if i is odd, otherwise false
*/
bool isOdd(int i);
There is a bit more to doxygen that might be useful, such as \throws
or \tparam
, or ///<
for trailing documentation on class members. It might also be worthwhile to show how to run doxygen, and that there is such a thing as a Doxyfile.
Furthermore, whether to start the comment block with /**
or each line with ///
or //!
is also possible. And you can use e.g. @param
instead of \param
.
I think we could introduce a slide on doxygen in the tools section.
To be added just after constexpr
On top of the global ExercisesCheatSheet.md
, there are some README.md
files in each subdirectory of code
, which were meant to play the role of detailed instructions for the exercices, while ExercisesCheatSheet.md
was meant to give the global point of view, and especially the order of the exercices.
Has this changed, and ExercisesCheatSheet.md
is now meant to contain anything ? If so, it would be better to remove the outdated README files. If not (my personal prefered option), we should make them up-to-date...
optional/any/variant would really benefit from a short example. the wording on the slides is correct but the students likely won't understand what it's useful for.
Godbolt should be mentioned and presented in the tools section.
And every code example should ideally have a link to a godbolt page with the code compiling there.
Next to the structured binding slides, we could consider adding a slide on CTAD (class template argument deduction). that works really great with structured bindings and multiple return types in case you don't want to define a struct for the return type:
auto f() { int a; double b; std::string c; ...; return std::tuple{a, b, c}; }
auto [a, b, c] = func();
Since this is a fairly generic idea, for starts we could introduce a simple slide linking to Core Guidelines (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines). Maybe we could cherry-pick a few guidelines that are commonly considered good, for eg:
(Fairly opinionated list ;)
I open this issue to collect all comments which cannot be done via PRs and were collected during the Aug HEP C++ Course.
Explain the implicit conversions danger, and the use of 'explicit'.
This issue was replicated from the old gitlab repo and was initially created by @chavid
Thanks for contributing! ❤️
If this issue is about a specific episode within a lesson, please provide its link or filename.
Keep in mind that lesson maintainers are volunteers and it may take them some time to
respond to your contribution.
To ensure that the right people get notified, you can tag some of the last
contributors with @githubname
.
Although not all contributions can be incorporated into the lesson
materials, we appreciate your time and effort to improve the curriculum. If you have any questions
about the lesson maintenance process or would like to volunteer your time as a contribution
reviewer, please contact the HSF training convenors (contacts here).
You may delete these instructions from your issue.
- HSF Training
it's useful to know what the compiler generates from a lambda function and there is a great website to look at that: https://cppinsights.io/lnk?code=I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGFsZ29yaXRobT4KCmludCBtYWluKCkKewogIHN0ZDo6dmVjdG9yPGludD4gdnsxLCAyLCAzfTsKICBpbnQgaW5jcmVtZW50ID0gNTsKICBzdGQ6OnRyYW5zZm9ybShiZWdpbih2KSwgZW5kKHYpLCBiZWdpbih2KSwKICAgIFtpbmNyZW1lbnRdKGludCB2YWx1ZSkgewogICAgICByZXR1cm4gdmFsdWUgKyBpbmNyZW1lbnQ7CiAgICB9KTsKfQ==&insightsOptions=cpp17&std=cpp17&rev=1.0
it's not just handy for lambdas, you can also check what the compilers creates for e.g. range-for
Hello @bernhardmgruber, @sponce,
when I did the operator exercise, I arrived at a bit different solution, and I wanted to post it here to figure out if the two approaches have specific advantages / disadvantages. I created a cleaned up diff to illustrate what I did differently below.
Specific points I want to discuss:
int
. I find that pretty logical, as this allows for collapsing 6 operators into two. Counterarguments?const &
I agree that it's totally fine to copy four ints if you test for equality. However, shouldn't we be showing the good practice that would get us better results if this wasn't just two ints per instance?--- solution/operators.sol.cpp 2022-02-28 16:12:00.000000000 +0100
+++ operators.cpp 2022-02-28 16:09:42.000000000 +0100
@@ -1,89 +1,77 @@
-#include <cassert>
#include <iomanip>
#include <iostream>
#include <numeric>
class Fraction {
- public:
- explicit Fraction(int i) : m_num(i), m_denom(1) {}
- Fraction(int num, int denom) : m_num(num), m_denom(denom) {}
+ public:
+ Fraction(int a) : Fraction(a, 1) { }. // Delegating constructors are awesome
+ Fraction(int a, int b) : m_num{a}, m_denom{b} {
+ Normalise(); // And I like to have the fraction always in a normalised state
+ }
int num() const { return m_num; }
int denom() const { return m_denom; }
That's our internal business:
- void normalize() {
- const int gcd = std::gcd(m_num, m_denom);
- m_num /= gcd;
- m_denom /= gcd;
- }
// One overload should do:
- Fraction& operator*=(int i) {
- m_num *= i;
- normalize();
- return *this;
- }
- Fraction& operator*=(Fraction f) {
- m_num *= f.num();
- m_denom *= f.denom();
- normalize();
- return *this;
- }
+ Fraction & operator*=(const Fraction & other) {
+ m_num *= other.m_num;
+ m_denom *= other.m_denom;
+ Normalise();
+ return *this;
+ }
// Also here we can use one to rule them all:
// The lcm might be unnecessary.
// On the minus side, It might be slow.
// On the plus side, it decreases the likelihood of overflows.
- Fraction& operator+=(int i) {
- m_num += i * m_denom;
- return *this;
- }
- Fraction& operator+=(Fraction f) {
- m_num *= f.denom();
- m_num += f.num() * m_denom;
- m_denom *= f.denom();
- normalize();
+ Fraction & operator+=(const Fraction & other) {
+ const auto lcm = std::lcm(m_denom, other.m_denom);
+ m_num = m_num * (lcm / m_denom) + other.m_num * (lcm / other.m_denom);
+ m_denom = lcm;
+ Normalise();
return *this;
}
+ private:
+ void Normalise() {
+ const auto gcd = std::gcd(m_num, m_denom);
+ m_num /= gcd;
+ m_denom /= gcd;
}
- private:
- int m_num, m_denom;
+ int m_num = 1, m_denom = 1;
};
-std::ostream& operator<<(std::ostream& os, Fraction r) {
- os << r.num() << "/" << r.denom();
+
+std::ostream & operator<<(std::ostream & os, const Fraction & frac) {
+ os << frac.num() << '/' << frac.denom();
return os;
}
// Multiplication
-Fraction operator*(Fraction r, int i) { return r *= i; }
-
-Fraction operator*(int i, Fraction r) { return r * i; }
-
-Fraction operator*(Fraction a, Fraction b) { return a *= b; }
+Fraction operator*(Fraction a, const Fraction & b) { return a *= b; }
// Addition
-Fraction operator+(Fraction r, int i) { return r += i; }
-
-Fraction operator+(int i, Fraction r) { return r + i; }
-
-Fraction operator+(Fraction a, Fraction b) { return a += b; }
+Fraction operator+(Fraction a, const Fraction & b) { return a += b; }
// Equality
-bool operator==(Fraction a, Fraction b) {
- a.normalize();
- b.normalize();
+bool operator==(const Fraction & a, const Fraction & b) {
return a.num() == b.num() && a.denom() == b.denom();
}
bool operator!=(const Fraction & a, const Fraction & b) { return !(a == b); }
// Relational
-bool operator<(Fraction a, Fraction b) {
- return a.num() * b.denom() < b.num() * a.denom();
+bool operator<(const Fraction & a, const Fraction & b) {
+ const auto lcm = std::lcm(a.denom(), b.denom());
+ return a.num() * (lcm/a.denom()) < b.num() * (lcm/b.denom());
}
-bool operator>(Fraction a, Fraction b) { return b < a; }
-bool operator<=(Fraction a, Fraction b) { return !(a > b); }
-bool operator>=(Fraction a, Fraction b) { return !(a < b); }
+bool operator>(const Fraction & a, const Fraction & b) { return b < a; }
+bool operator<=(const Fraction & a, const Fraction & b) { return !(b < a); }
+bool operator>=(const Fraction & a, const Fraction & b) { return !(a < b); }
void printAndCheck(const std::string & what, const Fraction & result, const Fraction & expected) {
Start with noexcept and the new way, only present the old fashion way after, if at all (keep the slides, but not necessarily go through them each time).
Or keep both and explain the differences
In the tools section we have a slide on makefiles and a short preview of GNU Makefiles is given. The slide also mentions cmake : portable, the current best choice
, but does not provide a small example itself or points to a introductory talk/tutorial.
I think we should add a slide on CMake and show a very basic CMakeLists.txt
:
cmake_minimum_required(VERSION 3.18)
project(hello CXX)
find_package(Threads REQUIRED)
add_executable(hello main.cpp util.h util.cpp)
target_compile_features(hello PUBLIC cxx_std_17)
target_link_libraries(hello PUBLIC Threads::Threads)
And then probably also a slide on how to build a CMake project:
mkdir build
cd build
cmake ..
ccmake . # for changing settings
cmake --build . # or just make on Linux
from @bernhardmgruber :
the examples are too much C, people should not be reminded again that malloc, free, strncpy, FILE, fopen, fputs, fclose, EOF exist. maybe we can find a C++ version that news an array for processing some numbers, the FILE example is actually good, because it shows that C++ can do better than C here. But I am afraid that students will remember these codes as something they can use. Like we show FILE* a couple of times but never std::ifstream, so what will students remember when they need to read a file?
In particular in the tool section, e.g. git, cmake, ...
Hi @sponce : Could you add a quick move notice to https://gitlab.cern.ch/sponce/cpluspluscourse/ so that people who still have the old link end up here?
@ALL Is there an agreement that CMake should be mandatory for the exercices ? If so, the old files Makefile
should be removed from git.
A choice has been made and should be enforced everywhere ?
Thanks for contributing! ❤️
If this issue is about a specific episode within a lesson, please provide its link or filename.
Keep in mind that lesson maintainers are volunteers and it may take them some time to
respond to your contribution.
To ensure that the right people get notified, you can tag some of the last
contributors with @githubname
.
Although not all contributions can be incorporated into the lesson
materials, we appreciate your time and effort to improve the curriculum. If you have any questions
about the lesson maintenance process or would like to volunteer your time as a contribution
reviewer, please contact the HSF training convenors (contacts here).
You may delete these instructions from your issue.
- HSF Training
Indeed we should have this somewhere, especially that we precisely show the consequences of such a mistake in one of the exercises (memory leak in that case).
Maybe we add a dedicated slide with a first point stating that destructors can also be virtual (not obvious for all I suppose) and what it means on which destructor is called.
Then your point would come as a natural conclusion, and I would just rephrase it to "if you write a class with at least one virtual method, declare its destructor \mintinline{cpp}{virtual}".
Originally posted by @sponce in #93 (comment)
I think you will all agree the operator exercise, in its current content, would be better placed at the end of the OO exercises. Also, if its aim is focused on operators, I would initially provide the basic implementation of Fraction, including the normalization stuff.
Thanks for contributing! ❤️
If this issue is about a specific episode within a lesson, please provide its link or filename.
Keep in mind that lesson maintainers are volunteers and it may take them some time to
respond to your contribution.
To ensure that the right people get notified, you can tag some of the last
contributors with @githubname
.
Although not all contributions can be incorporated into the lesson
materials, we appreciate your time and effort to improve the curriculum. If you have any questions
about the lesson maintenance process or would like to volunteer your time as a contribution
reviewer, please contact the HSF training convenors (contacts here).
You may delete these instructions from your issue.
- HSF Training
Hello @sponce after compiling the C++Courser.tex
when switching to true
\setboolean{onlybasics}{true}
Some of the slides specifically the ones labeled
Are empty completely.
I don't really seen any problems that could be causing this. Am I missing something?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.