funcPtr as argument, with default value

Suppose you write a dumpTree() which takes a “callback” parameter, so you can invoke callback(aTreeNodeOfTheTree).

Sounds like a common requirement?

Additionally, Suppose you want “callback” to have a default value of no-op, basically a nullptr.

Sounds like a common requirement?

I think c/c++ doesn’t have easy support for this. In my tested code https://github.com/tiger40490/repo1/blob/cpp1/cpp/algo_binTree/binTreeUtil.h, I have to define a wrapper function without the callback parameter. Wrapper would call the real function, passing in a nullptr as callback. Note nullptr needs casting.

Advertisements

[19] q[extern] idiosyncracies

Despite my numerous summaries, I could never reach the bottom of this keyword.

http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/ has good details like

int x;          // is the same as
extern int x{}; // which will both likely cause linker errors if placed in header.

extern int x;   // while this only declares the integer, which is ok.

friend to a class template

Similar to java reflection, void pointers, reinterpret_cast etc, friend is a powerful keyword in real projects, with GTD power. The rules are a bit tricky when you combine friend + template.

I think this is a relatively useful IV knowledge pearl as it demonstrates a fundamental concept — each template instantiation (“concretized template class”) is treated as a distinct class.

[[ARM]] P351 stipulates that

* A simple non-template friend introduced into a class template is a friend to ALL instances of the class template.

That’s the simple case.

* Now another common scenario — the class template C2 has a dummy type T, and the friend is another template F3 parameterized with the same type T. Now there’s a one-to-one friendship:

  • F3<float> is a trusted friend to C2<float>
  • F3<Acct> is a trusted friend to C2<Acct>

 

 

both base classes”export”conflicting typedef #MI

Consider class Der: public A, public B{};

If both A and B expose a public member typedef for Ptr, then C::Ptr will be ambiguous. Compiler error message will explicit highlight the A::Ptr and B::Ptr as “candidates”!

Solution — inside Der, declare

typedef B::Ptr Ptr; //to exclude the A::Ptr typedef
// This solution works even if B is a CRTP base class like

class Der: public A, public B{
  typedef B::Ptr Ptr;
};

const vector{string} won’t let you modify strings #ChengShi

Point #1: a const vector only gives out const references. In this case, reference to const string objects.

My friend ChengShi said he has never seen const vector<const string>, because const vector<string> is good.

Point #2: In fact, my experiment of q[vector<const string>] can’t compile. Why?

https://stackoverflow.com/questions/17313062/vector-of-const-objects-giving-compile-error explains that in vector<T>, T must be assignable!

VLA is supported in C99 not c++

https://www.geeksforgeeks.org/variable-length-arrays-in-c-and-c/ has pointers to

[[c++primer]] P113 says that as of c++11, array size has to be known at compile time.

— java arrays are VLA i.e. run-time allocated.

Java array is allocated on heap.

Are arrays on heap always run-time allocated, such as vector and hash table? I think so.

q[struct]^q[class] in c++

–difference: by default,

  • deriving from a q[struct] is public derivation
  • deriving from a q[class] is private derivation
  • P 243 [[ARM]] explains why.
  • Best to specify explicitly private or public

–difference: members (including static) default to public in a struct

–difference: keyword q[class] is usable in template<class X>

–difference: q[struct] is a keyword in C and C has a few other syntax rules about q[struct]

dummy param in c++func

I used to name unused parameters of myfunction as “dummy”.

  • now I also use ‘_’. I think this also works in python
  • now I also use nothing as in void fn(T*)

Not always better than ‘dummy’ but at least this kind of compiler knowledge is useful in troubleshooting.

I don’t name the parameter “unused” as it is a confusing name.

t_implBestPractice^t_idiom^t_c++patt^namedDesignPatt^t_c++ECT66^c++tecniq^t_workTimeSaver

  • t_c++pattern — must be a named pattern
  • t_c++idiom — must be well-established small-scale
  • t_ECT and t_c++idiom are mutually exclusive
  • t_tecniq — higher than syntaxTips, less selective than t_c++idiom or t_c++pattern but Should NOT be dumping ground
  • t_implBestPractice is like gentmp

c++enum GTD tips: index page

declare variables ] loop header: c^j #IF/for/while

Small trick to show off in your coding test…

Background — In short code snippet, I want to minimize variable declarations. The loop control variable declaration is something I always want to avoid.

https://stackoverflow.com/questions/38766891/is-it-possible-to-declare-a-variable-within-a-java-while-conditional shows java WHILE-loop header allows assignment:

List<Object> processables;
while ((processables = retrieveProcessableItems(..)).size() > 0) {/*/}

But only (I’m 99% sure) c++ WHILe-loop header allows variable declaration.

The solution — both java/c++ FOR-loop headers allow variable declaration. Note the condition is checked Before first iteration, in both for/while loops.

update — c++0x allows variable declaration in IF-block header, designed to limit the variable scope.

if (int a=string().size()+3) cout<<a << ” = a \n”; // shows 3

ensure operator<< is visible via header file

If you define operator<<() for a basic ValueObject class like Cell, to be used in higher-level class like Board, then you need to make this declaration visible to Board.cpp via header files.

If you only put the definition of operator<<() in a ValueObj.cpp and not the ValueObj.h, and you link the object files ValueObj.o and Board.o, everything compiles fine. When Board.cpp calls operator<< on this Cell object it would use the default operator<< rather than yours.

demo: static method declare/define separately n inherited

Low complexity in this demo, but if you lack a firm grip on the important details here, they will add to the complexity in a bigger code base.

  • When subclass is compiled, compiler complains about undefined sf() since it sees only the declaration. You need “g++ der.cpp base.cpp”.
  • Note the static method is inherited automatically, so you could call der::sf().
#include <iostream>
struct base{
  static void sf();
};
///////// end of header /////////
#include "base.h"
using namespace std;
void base::sf(){ // no "static" please
  cout<<"sf"<<endl;
}
///////// end of base class /////////
#include "base.h"
using namespace std;
struct der: public base{};
int main(){
  der::sf();
}
///////// end of sub class /////////

std::vector-of-containers: initializer list

Typical example: If you heavily use a vector of map, it’s tempting to use a vector of pointers to maps. The java way.

If you drop the “pointers to”, then when you retrieve the map from the vector, you often get a copy, unless you save the return value in a reference variable

By the way, here’s an initializer for std::map:

vec.push_back(map<int, int>{{32,1}} );

c++ for-loop header flexibilities

size_t countLinkedNodes(){
  size_t ret=0;
  for (Node * i=head; ; 
       ++ret, i=i->next){ //<-- different data types
    if (i == NULL) return ret; //<-- more control+clarify to move part 2 out of header!
  }
}

c++trick: pbref void max() on a list

I feel this technique may be needed somewhere else. In this example, we can move the amax() body into the for-loop!

// call by reference is used in x
template<class T, class U> static inline void amax(T &x, U y){
  if (x < y)
  x = y; //put bigger value into x
}

int main(){
  int array[] = { 4, -5, 6, -9, 2, 11 };
  int max_val = array[0];

  for (auto const &val : array)
    amax(max_val, val);

  std::cout << "Max value = " << max_val << "\n";
  return 0;
}

 

vector initializer: disallowed in field declaration until c++11

in a field declaration, you face restrictions:

vector<int> vec; //acceptable
vector<int> vec(9); // field initialization, disallowed until C++11. See https://stackoverflow.com/questions/24149924/has-the-new-c11-member-initialization-feature-at-declaration-made-initializati

You can write this kinda code in a *local* variable definition though.

typedef as prefix: syntax demystified

I find the typedef syntax not as simple as it appeared. http://stackoverflow.com/questions/3783016/fundamental-typedef-operand-syntax is the best explanation of the very confusing typedef syntax.

        int x; // declares a variable named ‘x’ of type ‘int’
typedef int x; // declares a type     named ‘x’ that is ‘int’
typedef char Decimal[20];
        int(*F)(size_t); // declares a variable named F of type ‘int(*)(size_t)’
typedef int(*F)(size_t); // declares a type     named F that is ‘int(*)(size_t)’

If you add the “typedef” prefix, instead of declaring a VARIABLE, you’ve declared a new TYPE-ALIAS instead.

c++syntax – class template – brief notes

[[absolutionC++]] covers ordinary class template and subclassing an /unconcretized/ class template. The syntax can be quite “flexible”. I guess some compilers might allow you to omit a symbol here or there. I prefer to follow the full syntax, same habit as with c# lambda expressions. Less likely to confuse myself when reading the code 6 months later.

In practice, we just need to follow a consistent syntax that works. No need to know if some unusual syntax is standard-conforming or not. But on some occasions like online quizzes, we may need to play the language lawyer. Let’s look at one simple aspect — It’s good to know where the dummy type name “T” or “S” should (not) be repeated.

After template , and when we first name our new class, we don’t put on its head —

template class BB   {};

However, subclassing this base class uses slightly different syntax —

template class DD: public BB{};

For an IKM c++ quiz, I used windows gcc to FAIL all of the below —

template class DD: public BB{}; //WRONG – new template must not be “decorated”
template class DD: public BB{}; // WRONG – base template must be “decorated”
template class DD: public BB{}; //WRONG – breaking both rules

Q: Do we ever use the class template BB without a concrete type and without a dummy type?
%%A: I haven’t seen any example. Looks like non-standard or obscure syntax

preprocessor syntax – a few tips #IKM

Never quizzed except in online QQ tests.

Based on an IKM question and my research on P372 [[ARM]]

1) redefine and “undef” a name is fine. I feel the “undef” feature is rather useful but unavailable in the compiler.

2) can check if a macro is defined or not, using
#if defined AA
#ifdef AA
#if !defined AA
#ifndef AA

3) a macro can appear in another preprocessor code, but this kinda code is frowned upon
#define AA2(jkl, xyz) {#xyz ## #jkl}
char result[] = AA2(def, abc); // will produce “abcdef” without space

c++ single-arg ctor is by default implicit converter

[[c++codingStandard]] point out the many subtle traps a beginner can hit when an implicit conversion is accidentally applied to her data type.

Therefore it’s good to spot any implicit conversion feature. For a custom class, there are only 2 ways to convert implicitly and one of them is a single-arg constructor. It’s implicit by default. You can disable the conversion capability by force it to be always-explicit

##common lvalue expressions in c++

Contrary to some claims, I feel an expression can be “usable as either L-value or R-value”.

Further, I feel most (or all?) L-value expressions are usable as R-values.

It’s instructive to look at all the expressions that can be L-value expressions

– pointer variable, but not a mere address. See http://bigblog.tanbin.com/2012/03/3-meanings-of-pointer-tip-on-delete.html
– pointer variable unwrapped, like *(myPtr)
– ref variable
– nonref variable
– subscript expression
– function returning a reference
– function returning a pointer? No

Warning ! I call this the little dark corner of L-value. Any time a function (or overloaded operator) modifies an object and returns a non-const reference thereto, you invite trouble because you allow it as a L-value. The modified object is now on the LHS of assignment!

in-line field initializer ] c++11

I believe the concise form of java-style field initializer is mostly legal in c++11 (except static fields — See P115 [[essential c++]]). In c++ lingo, “initializer” usually refers to one special part of a ctor, but here I focus on in-line initializers like

float myField = 0.11073;

Q: can you inline initialize the following entities?

  • case: static field of a class? No unless const integral types. Must be initialized (One-Definition-Rule) outside the class
  • case: instance field of a class? inline field initializer allowed since c++11. See https://stackoverflow.com/questions/13662441/c11-allows-in-class-initialization-of-non-static-and-non-const-members-what-c
  • case: instance field of type std::string or STL container? Allowed but no need to specify any initializer. These component-objects are automatically initialized to “empty”. I tested in my CRAB project in MVEA.
  • case: local variable? Yes … Best practice. Otherwise compiler can silently put rubbish there!
  • case: local static variable?Yes but no need… because Default-initialized!
    • Note the initialization happens only once, ignored on subsequent encounters
  • case: global variable? Allowed
  • case: file-scope static variable? Allowed
  • .. These rules are messier than java
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt; // without it, "string" is different type in MSVS!
using namespace std;

float global = 0.1;
static float file_scope_static = 0.1314;

struct Test {
	float instance_field = 0.3; // since c++11
	string instance_field_str = "instance_field_str"; // no-initializer also safe.
	static float static_field;
};
float Test::static_field = 0.4;

int main()
{
	float local = 0.2;
	static float local_static = 0.793;
	cout &amp;lt;&amp;lt; Test::static_field &amp;lt;&amp;lt; endl;
	Test t;
	cout &amp;lt;&amp;lt; t.instance_field_str &amp;lt;&amp;lt; endl;
	cout &amp;lt;&amp;lt; t.instance_field &amp;lt;&amp;lt; endl;
	cout &amp;lt;&amp;lt; file_scope_static &amp;lt;&amp;lt; endl;
	cout &amp;lt;&amp;lt; local_static &amp;lt;&amp;lt; endl;
	return 0;
}

operator << must be a friend function #tested

P 331 [[absolute c++]] gives the standard signatures of operator <<

— sound bytes —
friend — It has to be a friend function. Without “friend” keyword, compiler complains.
free function — required
method — is not possible. For a method, host object must be on the LHS of the operator, but q[ operator<< ] needs cout on LHS

[09]a function as a friend to 2 classes: syntax rule

“I name my friends!” I’m a class with private fields/methods. I can name another class to be a “friend-class”, so all its instance can access private members of my instance.

Now friend-function — I can also name a function as my friend. The function is identified by the full prototype (including const, return type …). Therefore, when i name the friend function, the syntax looks …..

The access controller treats each function [1] as an “thingy”, a special thingy in a running process, with its own identity (and address).

Now you can understand that a function can be friend to 2 classes.

[1] non-member, non-friend functions included, and also overloaded operators

See also http://newdata.box.sk/bx/c/htm/ch15.htm for transfer and inheritance resitrictions

## c++ syntax monsters

* constructor calls without new — see other posts.
* initializers in constructors
* array of pointers (P234 [[24]])
* function parameters — reference types
* copy constructor
* constant pointer to constant object
* assignment operator overloading
* function pointers, and (worse still) function pointers to member functions
* generic functions and (worse still) generic classes

A crude progress bar of a learner is these “chapters”….

variable type declaration: when using container of pointers

Suppose you have a container of (raw) pointers — very common requirement. Almost anything you do would require an iterator (which works like a double-pointer). The iterator declaration would include the asterisk, like

   map<Account, Book*, less >::iterator

If an algorithm needs a functor (quite common) and if the functor operator() takes an argument, what’s its actual type to replace T in ? Book or Book*

Answer — Book*. In fact, you can safely assume T * is the correct type everywhere. See P90 [[effSTL]]

c++ : first thing in parentheses of a func prototype

A parenthesis indicates a function call/prototype. The latter is a real readability issue — If there’s an unreadable param, then function call won’t be simple — doomed.

“First part” inside the parenthesis of a prototype is a parameter_type_specifier, just like variable declarations. However, a variable declaration is (and reads) simpler — it has 0 or 1 “=”, and everything on the left consists of the variable type and the variable name. There’s no obligatory “distractions”.

For a function prototype, there are other params and there’s a context ie the function as a whole. The function makes sense only as a whole [1]. It’s generally ineffective to try and interpret a “first part” without context. Therefore when you encounter a monstrous “first part”, you have to swallow it along with the context — more indigestion.

[1] In the same vein, a non-static field/method in isolation has limited meaning compared to the class as a whole. We are trained to think in terms of functions — deep rooted in our psyche. Function is the standard level of abstraction.

Now let’s look at some of the things that wash up as “first part”.

* a dummy type (template param) like T, S or a misleading name like InputIterator.
* indistinguishable from type params, we see type aliases defined in typedef. Like size_t.
<=== These are the 2 deceptive kind of "first part", as they often resemble user-defined class types.

* since T is allowed, so is pair
* a specialized template — since pair is allowed, so is vector
* an iterator, like std::vector::const_iterator
* functors like ….?

To make things worse, in the “first part” we also see ptr/ref to the above items, such as
– ref/ptr to a type param T
– ptr or ref to a type alias
– For template names, things get complicated — we can get vector and vector*. Example qq[ Property& ] as in [[pricing]] P51
— throw in iterator, you can get qq[ map(K,V*)::iterator* ]

In java, a method param can be as complicated as Map<T, List> but for C++ as soon as ref/ptr meets templates, complexity quadruples.

Some people put in a function ptr in the “first part”. I feel this should be a typedef.

double-colon q[ :: ] in c++

Recently I hit this confusion multiple times. The compiler is not confused because the usage scenarios are distinct —

  1. usage — namespace1::free_func2(). Example – you can specify std::swap() instead of your local swap()
    • somewhat similar to java package separator the dot
  2. usage — classA::staticMethod1()
  3. usage (very useful) — superclassA::instanceMethod3(). This is equivalent to this->superclassA::instanceMethod3() //tested
  4. usage — classB::localType

Actually, the first 2 scenarios have similar meanings. Java simply merged both into the dot.

boost::this_thread::get_id() shows two usages.

I believe a field name can replace the function name.

MyNamespace1::MyNamespace2::j = 10; // nested namespace
std::terminate() and ::operator new() are similar to System.java and Runtime.java methods.

In a class template, the #2 and #4 usages can confuse the compiler. See P670 [[c++primer]].

save a literal string in various simple data holders

— basic char pointer
char * ptr  = “and”;
char const * const_ptr = “and”;

— char array
char charArray[] = “and”;
char const  constCharArray[] = “and”;

— std::string
std::string std_string = “and”;

— std::string to vector of char.
std::vector<char> vc (std_string.begin(), std_string.end()); //

(2/3 of C/C++ coding tests involve strings…)

"star shines too bright" (but less than ++

The asterisk i.e. dereference operator binds Tighter than +/- operators, so

   *ptr+1 // bug

is evaluated as the nonsensical (*ptr)+1. I call this problem “star Binds too Tight” or “star Shines too Bright

Solution 1 — For pointer arithmetic, you must do *(ptr+1)

Solution 2 — for arrays, no parens needed here. Subscript binds tighter than star

   *orderLookup[i] // same as *(orderLookup[i])

Solution 3 — the increment “++” binds tighter than the star, so you can use

   *++ptr // same as *(++ptr)

Solution 3XXX (wrong!) — this means something else —

   *ptr++ // same as *(ptr++)

See also http://blog.tanbin.info/2011/02/p-and-p-operator-precedence.html

x++ vs ++x

echo ++$x means “increment first, then evaluate” => returns the modified value
echo $x++ means “evaluate, increment last” => returns the unmodified value

Applies to Java, PHP, Perl and any language.

Many (including experienced) programmers are fuzzy about the difference. It’s best to do

x++; if (x….) instead of if(++x …)