Jump to content

C++: Difference between revisions

4,498 bytes added ,  8 January 2020
(26 intermediate revisions by the same user not shown)
Line 1: Line 1:
__FORCETOC__
__FORCETOC__
C++ is a very popular and powerful language which includes all the low-level features of [[C_(programming_language) | C]] (e.g. pointers, operator overloading) along many high-level features (regex, STL containers) thanks to the C++ standard library.<br>
Some people may think of it as an object-oriented version of C.


==Usage==
==Usage==
Line 14: Line 16:


===Syntax===
===Syntax===
====Main====
All C++ programs launch in a <code>main</code> function.
Similar to [[C]], the arguments are <code>int argc</code> and <code>char *argv[]</code>.
These can be easily converted to a <code>std::vector<std::string></code> for convenience.
<syntaxhighlight lang="cpp">
#include <string>
#include <vector>
int main(int argc, char *argv[]) {
  std::vector<std::string> args(argv, argv + argc);
  // Your code here
  return EXIT_SUCCESS;
}
</syntaxhighlight>
====Headers====
[https://stackoverflow.com/questions/10694255/cmath-vs-math-h-and-similar-c-prefixed-vs-h-extension-headers Reference]
C++ includes C-headers such as <code>math.h</code> and <code>cmath</code>.<br>
The C-style header will place everything in the global namespace while the C++ header will place everything in <code>std</code>.<br>
You should use <code>cmath</code>.
====Lambda Expressions====
====Lambda Expressions====
[https://en.cppreference.com/w/cpp/language/lambda Reference]
[https://en.cppreference.com/w/cpp/language/lambda Reference]


====Casting====
====Casting====
Line 26: Line 47:
If you're casting between things but do not want to change the bit-pattern (e.g. binary data or pointers), you can also use <code>reinterpret_cast</code>.
If you're casting between things but do not want to change the bit-pattern (e.g. binary data or pointers), you can also use <code>reinterpret_cast</code>.


===Array===
===String===
<code>#include <array></code><br>
<code>#include <string></code><br>
In C++, you can use <code>std::vector</code> which gives you a resizable array.
 
This will allocate an array in the heap.<br>
<syntaxhighlight lang="cpp">
 
// c-str to string
char *old_string = "my c-style string";
string cpp_string(old_string);
 
// string to c-str
cpp_string.c_str();


[https://shendrick.net/Coding%20Tips/2015/03/15/cpparrayvsvector.html array vs vector]
// char to string
If you need a static sized array, you can use <code>std::array</code> in the <code>array</code> header.<br>
char my_char = 'a';
This wrapper around C-style arrays gives us size information and allows the array to be passed around by reference while keeping the array on the stack unlike <code>std::vector</code>.<br>
string my_str(1, my_char);
If you want to allocate a static array on the heap, you can do so as follows:
<syntaxhighlight lang="C++">
auto my_arr = std::make_shared<std::array<char,64>>();
</syntaxhighlight>
</syntaxhighlight>


===String===
<code>#include <string></code><br>
====String Interpolation====
====String Interpolation====
[https://stackoverflow.com/questions/10410023/string-format-alternative-in-c Reference]
[https://stackoverflow.com/questions/10410023/string-format-alternative-in-c Reference]
Line 58: Line 81:
}
}
</syntaxhighlight>
</syntaxhighlight>
====Buildings Strings====
[https://www.fluentcpp.com/2017/12/19/build-strings-from-plain-string-up-to-boost-karma/ The Complete Guide to Building Strings In C++]<br>
There are multiple ways of buildings strings in C++.<br>
Strings are mutable in C++.<br>
I typically use <code>+</code> or <code>ostringstream</code> to build strings.
===Filesystem===
===Filesystem===
<code>#include <fstream></code><br>
<code>#include <fstream></code><br>
Line 86: Line 116:
#include <cerrno>
#include <cerrno>


std::string get_file_contents(const char *filename)
std::string get_file_contents(std::string filename)
{
{
   std::ifstream in(filename, std::ios::in | std::ios::binary);
   std::ifstream in(filename, std::ios::in | std::ios::binary);
Line 96: Line 126:
     in.seekg(0, std::ios::beg);
     in.seekg(0, std::ios::beg);
     in.read(&contents[0], contents.size());
     in.read(&contents[0], contents.size());
    in.close();
     return contents;
     return(contents);
   }
   }
   throw(errno);
   throw(errno);
Line 223: Line 252:
</syntaxhighlight>
</syntaxhighlight>


==Containers==
===Utility===
===unordered_set===
<code>#include <utility></code><br>
====std::move====
[https://en.cppreference.com/w/cpp/utility/move Ref]<br>
Use <code>std::move</code> to move containers.
 
===Algorithm===
====std::find====
[https://en.cppreference.com/w/cpp/algorithm/find Reference]<br>
 
==STL==
STL is the Standard Template Library.<br>
STL can either refer to the 1994 original STL implementation by Stepanov and Lee from HP or the general set of algorithms, containers, functions, and iterators.<br>
Many STL containers are now built into the standard library (std) of C++.<br>
This section focuses only on the portions of STL which have been incorporated into the C++ standard library.
 
===Simple Containers===
====std::pair====
 
===Sequences===
====std::array====
<code>#include <array></code><br>
In C++, you can use <code>std::vector</code> which gives you a resizable array.
This will allocate an array in the heap.<br>
 
[https://shendrick.net/Coding%20Tips/2015/03/15/cpparrayvsvector.html array vs vector]<br>
If you need a static sized array, you can use <code>std::array</code> in the <code>array</code> header.<br>
This wrapper around C-style arrays gives us size information and allows the array to be passed around by reference while keeping the array on the stack unlike <code>std::vector</code>.<br>
If you want to allocate a static array on the heap, you can do so as follows:
<syntaxhighlight lang="C++">
auto my_arr = std::make_shared<std::array<char,64>>();
</syntaxhighlight>
 
 
====std::vector====
[https://en.cppreference.com/w/cpp/container/vector Reference]<br>
Use vector for almost everything...<br>
It is an ArrayList.<br>
Note that <code>vector<bool></code> is not an array of bools.<br>
This has several nuances so you should use <code>vector<char></code> instead.<br>
<syntaxhighlight lang="c++">
// Basics
vector my_vec;
// Vector with size 5
vector my_vec(5);
// Vector with size 5 initialized to 1
vector my_vec(5, 1);
 
// Length of vector
my_vec.size();
 
// Equivalent to size()==0
my_vec.empty();
 
// Equivalent to my_vec[0];
// Undefined on empty vectors
my_vec.front();
 
// Equivalent to my_vec[my_vec.size()-1];
// Undefined on empty vectors
my_vec.back();
</syntaxhighlight>
 
====std::deque====
Double-ended queue
 
====std::list====
 
===Container adaptors===
====std::queue====
[https://en.cppreference.com/w/cpp/container/queue Reference]<br>
<syntaxhighlight lang="c++">
 
</syntaxhighlight>
 
====std::stack====
[https://en.cppreference.com/w/cpp/container/stack cppreference]
<syntaxhighlight lang="cpp">
std::stack<char> my_stack;
 
// Push to stack
// You can also use emplace
// Returns void
my_stack.push('a');
 
// Peek
// Always make sure stack is not empty
char top = my_stack.top('a');
 
// Pop
// Note: returns void
// Always make sure stack is not empty
my_stack.pop();
</syntaxhighlight>
 
===Associative Containers===
Also known as maps or associative arrays.
====std::unordered_set====
<code>#include <unordered_set></code><br>
<code>#include <unordered_set></code><br>
This is a hashset.<br>
This is a hashset.<br>
<syntaxhighlight lang="cpp>
<syntaxhighlight lang="cpp>
unordered_set<int> my_set;
std::unordered_set<int> my_set;
// add things to myset
// add things to myset
my_set.insert(5);
my_set.insert(5);
Line 234: Line 359:
my_set.find(5) != my_set.end();
my_set.find(5) != my_set.end();
</syntaxhighlight>
</syntaxhighlight>
====std::unordered_map====
;Custom Keys
How to use a rational number as a key in C++
<syntaxhighlight lang="C++">
struct Fraction
{
    int num;
    int den;
    bool operator==(const Fraction &other) const {
        return num*other.den == den * other.num;
    }
    Fraction(int a, int b) : num(a), den(b) {}
};
</syntaxhighlight>
==Boost==


==Programming Styles==
==Programming Styles==
Line 244: Line 388:
[https://gist.github.com/bkaradzic/2e39896bc7d8c34e042b Reference]<br>
[https://gist.github.com/bkaradzic/2e39896bc7d8c34e042b Reference]<br>
Somewhat opposite of modern C++.<br>
Somewhat opposite of modern C++.<br>
Basically only use C++ for its classes. Do everything else C-style.  
Also known as "C with Classes"<br>
Basically only use C++ for its classes. Do everything else C-style.<br>
The main benefit is compatibility with older compilers/libraries and easier understanding for people less familiar with newer C++ features.
The main benefit is compatibility with older compilers/libraries and easier understanding for people less familiar with newer C++ features.
*Don't use C++ runtime wrapper for C runtime includes (<cstdio>, <cmath>, etc.), use C runtime instead (<stdio.h>, <math.h>, etc.)
* Don't use C++ runtime wrapper for C runtime includes (<cstdio>, <cmath>, etc.), use C runtime instead (<stdio.h>, <math.h>, etc.)
*Don't use stream (<iostream>, <stringstream>, etc.), use printf style functions instead.
* Don't use stream (<iostream>, <stringstream>, etc.), use printf style functions instead.
*Don't use anything from STL that allocates memory, unless you don't care about memory management.
* Don't use anything from STL that allocates memory, unless you don't care about memory management.
* Don't use exceptions.
* Don't use RTTI.


==Boost==
==Useful Libraries==
==STL==
A list of useful libraries
STL is the Standard Template Library. Many containers from STL are now built into the standard library (std) of C++.
===cxxopts===
[https://github.com/jarro2783/cxxopts Link]<br>
A header-only C++ argument parser.<br>
Note that if you already use Boost, you can use <code>Boost::Program_options</code> instead.
===Eigen===
{{main | Eigen (C++ library)}}
A C++ linear algebra library.