Cpp lang

From PeerFreedom Wiki
Jump to navigation Jump to search

See

  • Cpp intro and list of subpages in "Cpp/*".

Operations

  • Operation result types (e.g. <unsigned int> + <int> results in <unsigned int> etc)

Cpp-resulttypes.png

  • Partial-specialization of function-templates is not allowed (TLDR: because functions are also overloading in addition to specializing so that would be too complicated to also partially-specialize; while classes do not overload so this works with classes). http://www.gotw.ca/publications/mill17.htm


drafts

This are very quick notes for further extending.


streampos vs size_t

http://eel.is/c++draft/iterator.range#itemdecl:17

common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>


  • Compilation and liker errors FAQ
    • "required from here" - (there is some error in code generated from a template (template instantiation) somewhere) and This line with "required from here" marks the line with code that results in generating a template, and that template somewhere else (in that template) leads to an error (which is usually listed in next error messages)
template <class T> T foo(T a, T b) {
  return b.length();  // <--- this will be an error, WHEN we instantiate for T=float.  (but would be fine for using with T=string)  
}

void use_it() { 
  float xxx=5, yyy=3.14;
  float zzz = foo(xxx,yyy); // <--- error "required from here" - because creating foo for T=float is the thing that leads to an error
}

unqiue_ptr with deleter

You should create unique_ptr with a custom deleter if you want to hold a raw pointer that needed to be deleted e.g. with free().

std::unique_ptr<char, decltype(&std::free)>
    t_copy { strdup(t), &std::free };

std::unique_ptr<char, std::function<void(char*)> > name_d( function_that_allocates() , [](char *ptr) { free(ptr); } );

std::unique_ptr<char, std::function<void(char*)> > name_d( function_that_allocates() , free );


safe integer

https://www.youtube.com/watch?v=93Cjg42bGEw

used for int-char, char-char conversions: selecting template that returns T for given T, otherwise returns conversion to int

https://godbolt.org/z/ixKG5Q

#include <type_traits>

template <typename T>
std::conditional_t<
  std::is_same_v<T, char>,
  int,
  T
> foo(T) {return {};}

template <>
int foo<char>(char) {
    return 42;
}


Instead of if constexpr use a specialized template class

If you do not have ability to use "if constexpr (condition)" (from C++17) then instead you can move the body of if into a class-template and specialize that class two times, once for the version when condition is true, and one for false (for "else" block).

Example:

https://git.peerfreedom.org/peerfreedom/pfp-cpp/blob/fa9a5aff986b1bea7435a4cf76da2e83d6d52f3a/src-test-perf/xint.cpp#L268

we create increment_sum_by_value<> specialized for true and for false and then use this template with the true/false expression as template-argument. In this example the class has also other template-arguments since it is used inside code that is already inside a template on <T1,T2,data_t>.

This example is marked with text "[example_instead_if_constexpr_use_template_class_spec]" if you are looking at other version of this file.

Pin dereference pointer on each use with lambda

auto & obj = * ptr;
obj.foo();
obj.bar();


auto parse = [this]() -> auto & { _check(m_read_parser); return * m_read_parser; } ; // instead of pin-pointer: always dereference
parse().foo();