static local var in function template

Each instantiation of the template gets a separate allocation of the static var, so it’s no longer singleton.

My HRT codebase illustrates my solution

baseclass(template)use subclass field+!vptr

A very restrictive context —

  1. the base and sub classes represent market data messages, used in a reinterpret_cast context, with zero padding. Therefore, vptr would add a pointer and mess up reinterpret_cast.
  2. multiple (say 11) subclasses have a “price” field, so I don’t want code duplication 11 times
  3. The field order is fixed in struct definition. Without this restriction, I would define the “price” field in a base struct and also a getPrice() method. With a subclass instance, CRTP could probably work like static_cast<Subclass const*>(ptr)->getPrice() but the “price” field’s physical offset would be be dictated by the compiler not according to my struct definition

My technique uses CRTP but no SFINAE no enable_if.

My technique is easier to /internalize/, as it relies on simple overload resolution + simple type deduction. In contrast, the SFINAE technique used in my RTS codebase is off-putting and alien to me

specialize class- but !!function- templates

A fundamental TMP technique is class template specialization.

Class templates’ flexibility can only be achieved via specialization but function templates’ flexibility can be achieved via overload ! Overload is much simpler than specialization.

In [[c++coding standard]], Alexandrescu/Sutter said “Don’t specialize func templates”, for multiple reasons.

After remembering this sound byte, it’s probably important to remember one of the reasons, for IV (halo) and zbs.

MI loses type info about subclasses

[[Alexandrescu]] pointed out a fundamental weakness in MI for library design — base classes “do not have enough type information to carry out their tasks”, and “MI loses type information (about subclasses) which abounds in templates”

This statement can only be understood based on TMP. I like and will repeat this statement in QQ interviews. If interviewer is knowledgeable enough about TMP to quiz me further, I would say

“TMP can be combined with inheritance. I don’t remember the various TMP techniques that make use of the type information of subtypes”.

TMP is a compile-time technique so type information is more available.

template specialization based on NDTTP=true

We know it’s possible to specialize a template for a concrete type like int or std::string, but I didn’t know that It’s also possible to

… specialize a (class or function) template for a particular compile-time const value (like “true”) of a NDTTP (like “bool flag”)

  • On [[Alexandrescu]] Page xii , Scott Meyers showed an elegant example of specializing for “true”. Note “true” is a value, not a data type !
  • P 34 has a longer example.

Note on reading TMP code — the template specialization syntax is clumsy and can add noise to the signal. Better ignore the syntax rules for now to focus on the gist.

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>

 

 

##5 understandable-yet-useful type traits for TMP

type_traits.h defines too many constructs but only a few are easy to understand and unambiguous:

  1. enable_if
  2. is_same
  3. conditional — https://en.cppreference.com/w/cpp/types/conditional. Not necessarily widely used but my favorite
  4. is_base_of — https://en.cppreference.com/w/cpp/types/is_base_of
  5. is_polymorphic — https://en.cppreference.com/w/cpp/types/is_polymorphic about virtual function
  6. — not so understandable
  7. is_pointer — ambiguous. I think it only knows about regular ptr and function ptr
  8. is_class and is_scalar — possibly useful to check T is a class vs a “simple” type
  9. — understandable but not so valuable
  10. is_abstract — having pure virtual function
  11. — neither very understandable nor highly valuable

I guess all of these type traits are class templates. The way to access the result is the (boolean) ::value member typedef usually, though enable_if_t evaluates to a type.

c++TMP: 9 fundamental features + little tricks

ranked:

  1. SFINAE — fundamental compiler rule for overload resolution
  2. template specialization
  3. NDTTP — non-type template param, widely used, probably most of the standard TMP
  4. within a class template, define member function templates or nested class templates, with additional dummy types, probably required by SFINAE
  5. Even if an actual type (eg, Trade) behind a dummy type T doesn’t support an operation in vector<T>, compiler can still instantiate vector<Trade> if you don’t use that operation. [[c++Primer]] P329 has examples.
  6. default arguments — for type-param (or non-type-param), a small syntactical feature with BIG usages

Tricks:

  1. #include <type_traits>
  2. member typedefs — a regular class can define member typedefs. but this trick is used much more in class templates

enable_if{bool,T=void} #sfinae,static_assert

  • enable_if is a TMP technique that hides a function overload (or template specialization) — convenient way to leverage SFINAE to conditionally remove functions from overload resolution based on type traits and to provide separate function overloads for different type traits. [3]
    • I think static_assert doesn’t do the job.
  • typically used with std::is_* compile-time type checks provided in type_traits.h
  • enable_if_t evaluates to either a valid type or nothing. You can use enable_if_t as a function return type. See [4]. This is the simplest way usage of enable_if to make the target function eligible for overload resolution. You can also use enable_if_t as a function parameter type but too complicated for me. [3]
  • There are hundreds of references to it in the C++11 standard template library [1]
  • type traits — often combined with enable_if [1]
  • sfinae — is closely related to enable_if [1]
  • by default (common usage), the enable_if_t evaluates to void if “enabled”. I have a github experiment specifically on enable_if_t. If you use enable_if_t as return type you had better put a q(*) after it!
    • Deepak’s demo in [4] uses bool as enable_if_t
  • static_assert — is not necessary for enable_if but can be used for compile-time type validation. Note static_assert is unrelated to sfinae. https://stackoverflow.com/questions/16302977/static-assertions-and-sfinae explains that
    • sfinae checks declarations of overloads. sfinae = Substitution failure is not a (compiler) error. An error would break the compilation.
    • static assert is always in definitions, not declarations. static asserts generate compiler errors.
    • Note the difference between failure vs error
    • I think template instantiation (including overload resolution) happens first and static_assert happens later. If static_assert fails, it’s too late. SFINAE game is over. Compilation has failed irrecoverably.
    • Aha moment on SFINAE !

[1] https://eli.thegreenplace.net/2014/sfinae-and-enable_if/

[2] https://stackoverflow.com/questions/30556176/template-detects-if-t-is-pointer-or-class

[3] https://en.cppreference.com/w/cpp/types/enable_if

[4] https://github.com/tiger40490/repo1/blob/cpp1/cpp/template/SFINAE_Deepak.cpp

[15] template type constraint : j^c++

java and c# templates can have constraints. If the template uses T->length() then the constraint says T must subtype a certain interface containing a length() method. C++ handles it differently.

(http://stackoverflow.com/questions/874298/c-templates-that-accept-only-certain-types presents other solutions like boost static_assert…)

http://stackoverflow.com/questions/122316/template-constraints-c points out

You can call any functions you want upon a template-typed value, and the only instantiations that will be accepted are those for which that method is defined. For example:

template <typename T>
int compute_length(T *value)
{
return value->length();
}
We can call this method on a pointer to any type which declares the length() method to return an int. Thusly:
string s = “test”;
vector vec;
int i = 0;

compute_length(&s);
compute_length(&vec);

//…but not on a pointer to a type which does not declare length():
compute_length(&i); //This third example will not compile.

This works because C++ compiles a new version of the template function (or class) for each instantiation. As it performs that compilation, it makes a direct, almost macro-like substitution of the template instantiation into the code prior to type-checking. If everything still works with that template, then compilation proceeds and we eventually arrive at a result. If anything fails (like int* not declaring length()), then we get the dreaded six page template compile-time error.

## template tricks for type constraint

  1. –Here are the compile-time validation/checks offered by c++:
  2. std::is_pointer and family — each function checks one type of pointer. Very specific and clean
  3. q[ = delete ]  — to eliminate specific concrete type args. Laser removal .. extremely clean. Scott Meyers pointed out this usage of q[=delete]. Does this work with SFINAE ??????? I didn’t find anything online
  4. std::enable_if() — see separate blogpost. Designed more More for SFINAE than type constraint
  5. sfinae — probably the most versatile, flexible and powerful
  6. static_assert? Can be combined with other techniques to implement compile-time validation and constraints. See https://github.com/tiger40490/repo1/blob/cpp1/cpp/template/SFINAE_ptrCheck.cpp

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;
};

::value^::type #typedef

This TMP technique is the simplest but not for the uninitiated.

In type_traits.h, many templates expose a ::value or ::type construct. Often these two “members” are the only visible output from the type trait meta-functions.

  • ::value is a static field, typically true/false
  • ::type is a member typedef, typically related to the type argument T, but can be “void” like in enable_if

 

template template param

Andrei Alexandrescu briefly introduced this technique .. I think he said it is one of the most powerful TMP techniques.

One common feature of templ-templ param — the param P “template<typename>P” is usually used as “P<S>”, where S is a sister parameter to P !

http://www.informit.com/articles/article.aspx?p=376878 has a good tutorial.

https://stackoverflow.com/questions/213761/what-are-some-uses-of-template-template-parameters shows operator<<(). I have it in my github https://github.com/tiger40490/repo1/blob/cpp1/cpp/lang_33template/containerOutputOperator.cpp

The variadic version is broken because the template tries to accept any class template having 1 or more parameters in the definition. This includes std::basic_string, which already has an operator<<() that conflicts with the variadic version.

This also helps me understand that the 2-param version (using templ-templ) is really a template that accepts any class-template having two type-params by definition. Note the two type-params can use default values.

— See my github demo https://github.com/tiger40490/repo1/blob/cpp1/cpp/lang_33template/tmpl_tmpl_param.cpp

First and possibly biggest challenge is — understand the limitation of traditional solutions. I would say this is 90% of the struggle for a novice.

 

## CRTP usageS #template Method

This blog post describes two usages of CRTP

I briefly read the excellent blog https://www.fluentcpp.com/2017/05/16/what-the-crtp-brings-to-code/. I feel CRTP is advanced for almost all the contexts I can think of. (In contrast,  I can see some “necessary” usages of SFINAE, such as the one in my little AddOrder.h)

https://stackoverflow.com/questions/262254/crtp-to-avoid-dynamic-polymorphism shows a simple [1] example of CRTP to replace virtual functions. How much efficiency improvement does it make? Questionable. I always say that if you want the lowest latency, then write selected modules in assembly language, and store it in hardware like FPGA.

[1] if there is anything simple in template meta-programming.

I have heard of several techniques to avoid virtual functions, but I believe the actual evidence (in terms of measured improvement in latency) is likely unconvincing or insignificant. Therefore, if CRTP is used to eliminate virtual function latency, then I am not sure how much value it adds.

There are other techniques to avoid “virtual”. I feel they are easier to understand than CRTP.

Sometimes CRTP is the only choice — if the virtual function needs its own template parameters, then compiler will complain that “function template can’t be virtual”. Rahul hit this complaint.

Q: for a true virtual method v1(), the derived class is not yet written when the base class is compiled. Later, Only at run time can the “system” pick the right implementation of v1(). How about CRTP?
A: base class is Not compiled ahead of the derived class. Each derived class includes a header defining the base class template.

——

Beside this “virtual-elimination” use case, CRTP has other applications (am still unfamiliar with), but if I’m asked in interviews I will only mention this one use case. One of the common “other usages” is TemplateMethod with compile time (not runtime) resolution, the 1st usage in the excellent blog . In the classic template method pattern, the “procedure” is published and finalized in the base class. Individual steps of the procedure are virtual methods, resolved at runtime. In the CRTP version, superclass methods call subclass methods, safely and cleanly. Superclass using subclass is a taboo in most contexts, but both traditional TemplateMethod and CRTP-TemplateMethod are notable exceptions.

The article didn’t clearly highlight a key point about this usage — The base class NumericalFunctions is general purpose, designed to be subclassed by anyone.  I could write a Temperature class to subclass NumericalFunctions too. This way, the code in NumericalFunctions is available for reuse.

https://github.com/tiger40490/repo1/blob/cpp1/cpp/template/CRTP_demo1.cpp is working code. Key points to remember about the code sample:

  • base-class — is a template with a dummy type “Sub”
  • derived classes — have the form “class Sub1 public Base<Sub1>”
  • the static dispatch (non-virtual) function in Base always static_cast “this” to *Sub.

 

c++template^java generics #%%take

A 2017 Wells Fargo interviewer asked me this question. There are many many differences. Here I list my top picks. I feel c# is more like java.

  1. (1st word indicates the category winner)
  2. C++ TMP is quite an advanced art and very powerful. Java generics is useful mostly on collections and doesn’t offer equivalents to most of the TMP techniques.
  3. java List<Student> and List<Trade> shares a single classfile, with uniform implementation of all the methods. In c++ there are distinct object files. Most of the code is duplicated leading to code bloat, but it also supports specialization and other features.
  4. java generics supports extends/super. C# is even “richer”. I think c++ can achieve the same with some of the TMP tricks
  5. c++ supports template specialization
  6. C++ wins — java doesn’t allow primitive type arguments and requires inefficient boxing. C# improved on it. This is more serious than it looks because most c++ templates use primitive type arguments.
  7. c++ supports non-dummy-type template param, so you can put in a literal argument of “1.3”
  8. c++ actual type argument is available at runtime. Java erases it, but I can’t give a concrete example illustrating the effect.

 

declare iterator]function template #gotcha

(Needed in some coding interviews and also in GTD!)

Update: With c++11, you can use the “auto” keyword and avoid the complexity.

If you drop the “typename” from the for-loop header, then compiler is confused

error: dependent-name ‘std::multiset::iterator’ is parsed as a non-type, but (template) instantiation yields a type
note: say ‘typename std::multiset::iterator’ if a type is meant

Basically, we need to be extra explicit to the confused compiler.

template<typename T> ostream & operator<<(ostream & os, multiset<T> const & l){
  for(typename multiset<T>::iterator it = l.begin(); 
      it != l.end(); ++it){
        os<<*it<<" ";
  }
  os<<endl;
}

SFINAE #sizeof#ptr2member as template param

https://jguegant.github.io/blogs/tech/sfinae-introduction.html is relatively simple, concise. Shows how to test T has method1()

https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/SFINAE is shorter and uses the same sizeof trick.

https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector is another illustration

–all 3 resource above use sizeof and function template (not class template) —

https://github.com/tiger40490/repo1/blob/cpp1/cpp/template/includes useful demo of my own code in production, powering the nyse+nyseAmerican real time market data parsers behind most of the biggest financial data sites.

When the compiler evaluates sizeof, which is a compile-time task, it would try one of the 3 func() overloads and check the winner’s return type[1] . Always exactly one of the 3 overloads can compile.

When T is AddRefreshOrderStruct, the compiler tries 1st overload, where AddRefreshOrderStruct needs a long field, and AddRefreshOrderStruct needs a sendTimeNS field. Pass! So the return type is int.

When T is EmptyStruct, the compiler tries the 1st overload, where EmptyStruct needs a long field … failed:( Only the last overload, the default overload, passes.

[1] the size of the return type is used to initialize the static const field!

The asterisk at end of the func declarations is needed as the func() argument will be NULL pointer. NULL pointer can match a pointer to any type.

TradeWeb c++IV

100% QnA interview. No coding no white-board no ECT no BP no algo no data structure.

System is Multi-threaded VC++/MSSQL.

One technical interviewer only. (The other 2 are behavior interviewers.) He is a director and looks very technical. I have met perhaps 3 to 5 interviewers focused on the fundamentals of a language/compiler. They pick one of 10 important parts of a language (like java, c++ or c#) and try to determine how well a candidate understands the key details and the rationales.

Below, Q’s are questions from this interviewer. A’s are my answers/guesses.

Q1: let’s talk about non-virtual dtor. You said there are problems in deleting a subclass instance via a base class pointer. Show an example.
(Now I think giving a non-trivial example requires non-trivial knowledge.)
A: Eg: subclass holds some resources to be explicitly released (via close() or disconnect()) in its dtor, but in our scenario only the base dtor is called. Subclass dtor is not invoked.

Q1b: if subclass dtor is invoked, does it always run the base dtor?
%%A: Yes guaranteed. See my blogpost.

Q1c: if a subclass dtor is virtual and you delete an instance via a subclass ptr, you said this is good and subclass dtor will run, so is the “virtual” unnecessary? In this case, what’s the difference between virtual dtor  vs non-virtual dtor?
%%A: yes in both cases the subclass dtor runs.  If your system is written such that you delete a subclass instance only via a subclass ptr and never superclass ptr, then drop the “virtual” to improve runtime performance.

Q3: Let’s talk about a static member function sf2() in class Base. If you have a reference to a Base instance, Can you call myInstance.sf2()?
A: yes

Q3b: if Base and Der both have a static method sf2()?
A: subclass sf2 tends to hide Base sf2. Static type of myInstance variable is used to determine which version is used.

Q3c: how about myPtr->sf2()? Obscure details that I don’t want to spend too much time on.
%%A: looks very odd, but if it compiles, then it’s static, never dynamic, binding, since there’s no ‘virtual’. See my code in https://github.com/tiger40490/repo1/tree/cpp1/cpp/lang_misc

Q4: when must you use the pointer “this”? Obscure details that I don’t want to spend too much time on.
%%A: ctor chaining? Actually chaining is supported in c++11 but not using “this”.
A: if there’s a field and a local variable of the same name, I use “this->” to disambiguate. CORRECT:) See
https://stackoverflow.com/questions/22832001/access-member-field-with-same-name-as-local-variable-or-argument
A: in my ctor (or method), i may want to print my address. Yes you can usually do that in the caller afterwards but not always
A (hindsight): Similarly, in my ctor (or method) I may want to conditionally save my address in some container. The conditional logic is not doable after the ctor.
A (hindsight): if I know the host object is in an array, I could do array arithmetic using “this” with precaution.
A: delete this. I have seen people doing it.
A (hindsight): CRTP
A (hindsight): if parent class has a const method m1() and non-const overload m1(), you can cast “this” to call either of them.
A (hindsight): what if inside a method you need to access a parent object field hidden by a host object field? Can you cast “this”? Yes tested but not a “must” use case. Alternative solution is B::nonStaticField
AA: sometimes you must return *this where the return type is HostClass&

Q4b: can you think of an example of using “this” to avoid access violation?

Q4h: why would anyone use ctor chaining? Why not call a common (non-static) setter method s2() from multiple ctors of the same class?
A: that setter has to be non-static!

Q4i: You think ctor should not call a non-static method?
%%A: it can, but I don’t do it. The host object is half-initialized, so the setter method must strictly perform field initialization and nothing else.

Q5: why do people use class templates? Note — Interviewer didn’t ask function templates.
%%A: avoid the cost of virtual functions

Q5b: Let’s look at using both class hierarchy and class templates.
%%A: not a good idea to combine them. STL has probably no virtual functions.

Q5c: Let’s see. You said you have a bunch of “payload” classes PL1/PL2/… and you want to use a container of PL1 and another container of PL2. Ok You said that’s a common use case of class templates unrelated to virtual functions. Suppose the container template requires each payload class to implement a method f2(). If f2 is provided by a base class, wouldn’t it be easier (can be virtual or non-virtual)?
A: If there’s a family of payload classes, like Shape, Rectangle, Square… then I feel it’s best practice to use a container of smart pointers. I think it reduces the risk of slicing, among other benefits.
A: if the payload classes don’t form a family hierarchy, then there is probably some template meta-programming technique to provide a default implementation of f2(). I’m no expert on template meta-programming.

lambda meets template

In cpp, java and c#, The worst part of lambda is the integration with (parametrized) templates.

In each case, We need to understand the base technology and how that integrates with templates, otherwise you will be lost. The base technologies are (see post on “lambda – replicable”)
– delegate
– anon nested class
– functor

Syntax is bad but not the worst. Don’t get bogged down there.

c++ OO vs templates – evolution from C

Am no expert on language evolution, but I feel c++ extends C primarily in two directions — 1) OO and 2) templates (and perhaps 3) exceptions)

Most introductory texts focus on OO. C++ sister (derivative) languages — java, c# etc — focused mostly on enhancing the c++ OO features and only added templates as an afterthought. OO, not template, has been the dominant paradigm since the 90’s. In contrast, I feel the art of template meta-programming feels kind of a dark and dying art.
Compared to OO, I feel c++ template meta-programming is more powerful more complex. Note STL is all template and no virtual function. I guess so are many popular Boost libraries.
C++ OO can become unwieldy (MI, hiding, slicing etc) and was significantly simplified in java. In comparison, I feel c++ template techniques are even more complex.
When a language feature becomes so complex, the number of competent practitioners will remain small. Case in point — threading. Most developers stick to battle-tested threading constructs only. Similarly, most app dev teams don’t bother to create templates except those trivial 50-line templates.
In fact, as of 2013, many active and influential projects are based on C not C++. With respect to language evolution, i don’t think any language has embraced the c++ template meta programming heritage wholesale, and is carrying the torch. Many new languages are more dynamic, simpler to use, and OO. They are based on C or JVM, not c++.

typedef: non-optional in this case

Someone asked me to write a utility function to print any STL container, in my own loop. I suggested we follow the STL convention to use iterator inputs. Echoed on http://stackoverflow.com/questions/4657767/how-to-templatize-a-function-on-an-stl-container-that-has-an-iterator. However, what if we pass the container itself as input (assuming it’s a standard-conforming container)?

template
void dump(const CT& cont) {
typedef typename CT::const_iterator iterator; //no choice
iterator i;
//won’t compile — CT::const_iterator i;
for(i = cont.begin();   i!= cont.end();   ++i){
cout<<*i <<” “<<endl;
}
}

This works but the typedef isn’t sugar-coating. Without it you get

dependent-name ` M::const_iterator’ is parsed as a non-type, but instantiation yields a type

Very loosely, CT::const_iterator i suggests to the compiler to create a concrete type for i but CT::const_iterator is not a generic type, not “concretized” [1]. Solution — The typedef dresses up this “generic type” as if it’s an end-user type, usable in a variable declaration

[1] remember the Barcap FMD eval objects?

%%jargon — describing c++ templates

The official terminology describing class templates is clumsy and inconsistent with java/c#. Here’s my own jargon. Most of the words (specialize, instantiate) already have a technical meaning, so I have to pick new words like “concretize” or “generic”

Rule #1) The last Word is key. Based on [[C++FAQ]]
– a class-template — is a template not a class.
– a concretized template-class — is a class not a template
————————–

“concretizing” a template… Officially terminology is “instantiating”

A “concretized class” = a “template class”. Don’t’ confuse it with — “concrete” class means non-abstract

A “unconcretized / generic class template” = a “class template”.
(Note I won’t say “unconcretized class”as it’s self-contradictory.)

A “non-template” class is a regular class without any template.

Note concretizing = instantiating, completely different from specializing!

“dummy type name” is the T in the generic vector

“type-argument”, NOT “parameter“, refers to an actual, concrete type like the int in vector

func ptr as template non-type param

This is the #1 eye-opener in [[essential c++]]

http://bigblog.tanbin.com/2012/03/non-dummy-type-template-parameters.html describes the background of Non-Dummy-Type parameters in a class template. Things like the maxRows in template class matrix_double. [[Essential c++]] succinctly describes that usage but also illustrates on P185 how you can put in a func ptr Type (not a dummy type) in place of the “int maxRows”. I find it a very powerful technique. (I guess java and c# take other routes since they don’t support NDT template parameters.) This is how I guess it works. 

First understand a real usage scenario and focus on a concrete class instantiated from such a template. At runtime such a class can have 888 class-instances, but they all share a single special “static field”, which is the function address[1] supplied to concretize the template.
If you later concretize the template with a 2nd function address, you get a 2nd concrete class. You can create 877 instances of this 2nd class. 
For the simple NDT, you supply an integer constant like 55 when you concretize the template matrix_double. Similarly, you supply a function address as a constant when concritizing our numeric_sequence template. More generally, any constant expression can be used for a NDT.
How useful is this technique? It allows you to concretize a template using a specific function address — a specific “behavior”. It could beat a static field in some cases. For example, You can concretize a given template
* once with type Account + AccountBehavior
* once with type Student + StudentBehavior
* once with type int + intBehavior
[1] the address of a real function, not a func ptr Type.

c++ template technicality – IKM findings

Never quizzed when I declare I’m no template wizard…

to specialize a func template,

template <typename T> void fn(T a){}
template<nothing here> void fn(char c){…} //empty param to specialize an existing func template

template<class T> void f(T arg){ cout<<arg<<endl;}
template<> void f<char>(char arg){ cout<<"char: "<<arg<<endl;}
// the <char> after f is optional !
int main() {
  f(1.3);
  f('a');
}
///////////////// Some<int> is distinct from Some<char> -- which is the basis of my friend caching factory in 
https://github.com/tiger40490/repo1/blob/cpp1/cpp/template/friendFactory.cpp 
template <typename T> class Some{
  public: static int stat;
};

template<typename T> int Some<T>::stat = 10;
int main(){
  Some<int>::stat = 5;
  cout<<Some<int>::stat<<endl;
  cout<<Some<char>::stat<<endl;
  cout<<Some<short>::stat<<endl;
  cout<<Some<long>::stat<<endl;
}

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

template expansion/instantiation c++^c#[[pro .Net perf]]

— Based on P154 [[pro .net performance]] —

A regular c++ class Dog has 2 forms i.e. source file and the compiled binary file (usually as a library).

In contrast, a c++ class template like a simple BigList has 1 form only. There’s no such thing as a compiled form of a class template (unlike java/c#). The BigList source is used only when we compile a concretized class based on the template, such as BigList. If we include BigList source in a project but never use it, then the compiler probably ignores it.

If BigList defines a method dance() that’s not used in BigList, then this method is ignored by the compiler. In contrast, an invoked method (such as add()) is “expanded” with the type-argument “string”, to become a concretized method, and then compiled. I feel the expansion mechanism is similar to macro expansion.

What if dance() contains something unsupported by string? Well, rest assured — not compiled.

In C#, BigList is not an “expanded” or concretized version of BigList.

4 basic "consumers" of an existing template #incl. subclass

Given an existing class template, [[c++timesaving Techniques]] Chapter 31 details 4 simple/basic “techniques” to use it as a consumer[1].

1) concretize and use it as a regular class. Most common and basic usage. This is how we use STL containers.
2) concretize and use it as a field of your own class. Simple composition.
3) concretize and derive from the concretized class
4) derived from the template unconcretized. You get another template. Classic extension. P678 and P684 [[absoluteC++]] explains the syntax

Other techniques not mentioned in this (beginner/intermediate) book
7) use it unconcretized as a field of your own template. Common usage of STL.
template class C7{vector v;};

8) template specialization

9) use it as a template type argument in another template. “Nested template”. P684 [[absoluteC++]]
template class C9: public multiset<vector >;

[1] Recall the distinction between a library codebase and a consumer codebase. A regular function or class we write can a consumer or part of some library. A class template is always in a library.

c++ most common nested template use case

If you feel someTemplate <anotherTemplate > is rarely needed in c++? think again.

To put any pointer into a container, you usually have a vector<shared_ptr >. In this template we have
* the most important container
* the most important smart pointer
* the most important boost library component
* the most important STL component

Also note that string is a value-like type just like int or char. You can use a string directly in a container or you can store a string smart-ptr in a container.

design a param as 1)non-type template arg ^ 2)ctor arg

Q: how do you choose to make “length=5” a ctor arg or a non-type template argument? For a context, you can imagine a custom array class template (D Duffy)

I feel non-type template arg was invented for a practical need but that history is not important. I feel the philosophical or technical reason for it is less important than the actual usage in practice, which I have not seen many. My rule is to avoid it and favor the more familiar ctor arg unless we see a compelling reason AND a proven usage pattern.

However, for self-practice we should feel free to play with it.

I believe [[Alexandresc]]  covers this.

c++ template instantiation – a few of the many rules

— Based on [[c++InANutshell]] —

Template declarations describe a class (or function) but do not create any actual classes (or functions). To do these things, you must instantiate a template.

Most often, you implicitly instantiate a template by using it. An Actual template instance requires a template type argument for each dummy type. The arguments can be
– explicit or
– implicit
** default arguments for class templates or
** deduced arguments for function templates, not class templates

default-initialize^value-initialize — new-expressions

Q: difference between new Dog and new Dog() with the parentheses?

http://www.cplusplus.com/forum/general/37962/ answers clearly
The first constructor – naked – provides what is called default initialization (unrelated to default ctor). Default initialization leaves the values of fundamental types (int, double, etc) uninitialized, i.e. arbitrary as in the graveyard. Therefore, with new Dog you get uninitialized chunk of memory with arbitrary values in the fields.

The second constructor – with parenthesis – provides what is called value initialization. Value initialization zeros fundamental types. Therefore, with new-Demo() you get zero-initialized chunk of memory – all fields in this case will be zeros.

–C++Primer P407 made it even clearer that default-initialize on the heap basically leaves the bits (of the real estate carved out of a graveyard) as they were left behind by the dead/freed/bulldozed corpses.

http://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make-a-difference-with-new/620402#620402 has good illustrations of 3 categories of classes and shows the behavior of new-Dog vs new-Dog(). Another contributor pointed out that the difference is usually negligible. “If there is such a constructor it will be used. For 99.99% of sensibly designed classes there will be such a constructor, and so the issues can be ignored.” However in practice, how many classes out of 100 are sensibly designed?

— to initialize the field (of type T) of a class template, 
P687 [[absoluteC++]] says we can skip the init since there’s no good default value for the unknown type T.

Stanley Lippman on P246 [[essentialC++]] says we could use T() even if T happens to be int.

[12]call`same method@unrelated types: template outshines java

Suppose pure abstract class Animal has a die() method, and so does Project, Product, Plant and Planet, but they don’t share a base class. How would you write a reusable function that invokes this method on a generic input object, whose type could be any of them?

Java can’t do this. In C++ you create

template<typename T>  f1(T input){ input.die(); }

If you pass an int into f1(), then you get compile time error. Probably a linker error. Is this SFINAE ? I doubt it.

STL algorithms routinely take an iterator argument and then call operator>() on the iterator. Now, this operator is undefined for a lot of iterator INSTANCES. I think only RandomAccessIterator category supports it.

Q: So how does STL make sure you don’t pass an object of ForwardInterator category into such a function?
A: use the template parameter type name (dummy type name) as a hint. Instead of the customary “T”, they put a suggestive dummy type name like “BidirectionayInterator” or “InputIterator”. If you ignore the hint you get compile-time error.

Now we understand that STL iterators have no inheritance hierarchy, but “stratification” among them.

non-dummy-type template parameters

(Note this topic is not related to template Partial specialization)

First, let’s distinguish a template parameter (like “T”) vs a template argument (like a class “Account”). For a NDTTP, the template parameter has a) concrete type and b) a parameter name, typically “size_t value” vs the template argument like “31”.

Simplest example: std::array template has 2 template parameters —

  1. a dummy type T
  2. a non-dummy type “size_t length”

std::array<Account, 31> concretizes the template with a concrete type Account and a value of 31.

Majority of class templates in practice have a dummy type (or multiple, but let’s stay focused) to signify an Unknown-type. For example, the STL vector can be “concretized” in memory to become a real CLASS when given a real type like “Account”. The real type replaces the dummy type. [[C++ primer]] is the first book I read that mentions a very powerful type of class template. I call it NDTTP i.e. non-dummy-type template parameter.

Background — What appears inside angle brackets after the keyword “template” is always a list of “tokens” or “thingies”. In most cases in practice, each thingy is a “typename T” or “class C”.

Now, the thingy can also be something like “int size”. This is known as a non-type template parameter. I call it a non-dummy-type template parameter, or NDT template parameter. a NDT is not a dummy type, but a real type with a parameter name. NDT declaration syntax is like a regular function parameter. NDT represents a dummy type pinned to a real type.  But how is NDT used when the push comes to the shove i.e. template instantiation (I prefer “template concretization”)?

Remember a real type argument like “AccountAllocator” in STL vector is a piece of information at the class level, not Instance level. When the vector is concretized in memory to become a real/concrete Class, the real class uses AccountAllocator Class. In the same vein, the NDT value is at class-level, not class-instance level nor at template level. That implies the “int size” value of 55 is a constant for the class, across all class instances.

In other words, when we convert a GENERIC “unconcretized” template matrix_double into a real class, the “int size” template parameter (NDT template parameter) is replaced by a value like 55, and treated as a class-level static constant. If we construct 9999 instances of the concrete matrix_double class, all of them share the same size=55.

A class template can have all its “tokens” be dummy types (standard practice), or all of them NDT (P861 [[c++primer]]), or a mixture.

See other posts about When the NDT arg is a specific func ptr like “revalue”. In contrast, given a functor class, you use a regular type param (more common), not a NDTTP.

templates in c++ standard library

Many (if not most) c++ standard library classes/functions are templates (except those from C). STL is part of it. See also the list in last item in [[more effC++]]

– string
– iostream
– auto_ptr

How about boost? All of the ones I have seen are templates.

boost thread
boost tuple
boost serialize
boost smart pointer
boost regex

specializing class templates (C++) #1 rule

Say you have Account objects to put into a Sorter class template. Generic Sorter was written for built-in types and uses operator-less-than (the left-arrowhead) in compare(), sort(), search() etc. However, Account class offers this->compareBalance() method and you want to use it in Account sorter. One solution is template specialization. Specifically, a specialization of the Sorter class template.

So You provide a custom definition of method compare(). How about other Sorter methods? There’s nothing to change in them so can we somehow “default” them to the Generic Sorter template?

Answer — no. As soon as you specialize the Sorter template for Account, your specialized template is disconnected from the original Generic Sorter template. Umbilical cord is cut once and for all. As described on (lower) P859 [[c++primer]], You must re-implement every public method. This is the Rule #1 in template specialization.

That was a regular/standard specialization. How about a partial specialization? Same answer.

Q: is the so-called specialized template a true template or just a regular class?
A: template. Difference is clear to the compiler. Syntax is vastly different[1]. A fully specialized template ironically has no dummy type, but it is technically still a “template” for creating classes[2], just like a document template. Only when you Instantiate the template with Account type, does the compiler actually create the real class. When given an Account type, the compiler will choose the specialized template over the generic or “default” template.

Here’s the paradox — in normal circumstances, a “document template” is meaningful when some section has dummy content. For example, a report template would have a dummy date, dummy author, dummy intro/summary, and dummy title. In a fully specialized template though, there’s nothing dummy, so is it a meaningful template? However, compiler still treats it technically as a template not a real class.

A partial specialization is like a report template with the dummy author replaced with a real author “hard-coded”. It is still meaningful as a template since it has *some* dummy content.

[1] template class Sorter {/*…*/} ; //note the syntax – template before the empty diamond
 no such thing when you instantiate a template. You instantiate a template simply in a variable declaration !
[2] though a fully specialized template can create no more than one class !

Re: what makes c++ templates difficult to master

Here are some of the reasons I now see c++ templates as monstrous.

1) you can put arbitrarily complex types into the angle bracket when you instantiate a template. Example – You can put an array of multimap of pointer to member functions in there

2) within a class template, you can create typedef involving the “T”. Common in STL. I feel typedef is supposed to simplify declarations but often hides hideous complexities beneath the carpet. The complexity doesn't disappear so when things go wrong, you need to lift the carpet and analyze the dirt beneath. Things get even worse when typdef is defined locally in a class template, when the T is an unknown type.

3) when templates meet inheritance. The syntax is too complex for me to grasp. I don't know if developers enjoy deriving from a class template while adding additional type params  (like adding T2 to an existing T).

What's your view on the complexity of templates?

Sooner or later if we were to investigate these “corners” of the C++ template system, we must ask “how is template instantiation implemented”. Is it code generation? If it is, then I actually feel macro expansion is much, much simpler and better understood than templates, though less powerful.

I feel without templates, c++ is at least 50% more complex than java, thanks to things like pointer to pointer to pointer (and reference to pointer to pointer), function pointers, pointer to member function, assignment/copy-ctor overloads, memory management, casts, pass-by-value vs reference and when each applies.

On top of those, templates add so much complexity that I feel most wall Street developers aren't competent to write templates. Wall Street developers can throw together large java/c# systems because those languages are simpler and more strict. Those languages check a lot of things for us at compile time, and disallow many things and take cares of many things at run time, so it's safer to be careless.

On Fri, Apr 1, 2011 at 1:52 AM, raiserchu  wrote:

Hmmm, I don't quite remember. that was 10+ years ago. Since you have also realized that, then that must be the reason (that you realized). It's easier to use than write. I guess just a lot of rules to remember and follow and a lot of cases. I like simple rules and simple cases/syntax, treat humans like human.
 

dissect`parametrized functor declaration-cum-construction

typedef void (*WorkerFunPtr)(const std::string&);

template<typename FunT,   // The type of the function being called
         typename ParamT> // The type of its parameter

struct Adapter {
   Adapter(FunT f, ParamT& p) : // Construct this adapter and set the
      f_(f), p_(&p) {}          // members to the function and its arg

   void operator( )( ) { // This just calls the function with its arg
      f_(*p_);        
   }
private:
   FunT    f_;
   ParamT* p_;  // Use the parameter’s address to avoid extra copying
};
void worker(const std::string& s) {} // a free function
int main( ) {
   boost::thread thr1(Adapter(worker, someStrVar)); // this line should be decomposed as
 
   Adapter // specialized type
        myAdapter(worker, someStrVar); // constructor

   boost::thread thr1(myAdapter);

Specializing a class template and then constructing an object is always a confusing process. Unfortunately we often have to do it in one line.
* specializing the Adapter template is simple enough, if we treat WorkerFunPtr as a simple type rather than a complicated typedef.
* constructing an object is simple enough
* However, the constructor is parametrized (since it’s in a class template), therefore the arguments have to match the actual types specified in the template specialization.
** worker is a function but implicitly converted to a function pointer. Its type does match the actual type WorkerFunPtr
** someStrVar does match the actual type std::string
==) Therefore this line constructs an object of the specialized type, using the 2 arguments — a func ptr and a string

Last lines passes the newly constructed myAdapter OBJECT to the thread constructor. Implicitly converted to qq/myAdapter.operator()()/ i.e. a no-arg function.
 

template and OO are orthogonal constructs

11) Template and OO are orthogonal constructs. Some might see a concrete template class as a subclass? Probably not. In classic OO Analysis and Design, there's no place for templates.

22) Template is one level higher than OO. So-called “Meta-programming”.

12) You can have template-only or OO-only systems, or you can have template+OO systems. Simplest is a template used in class derivation. There are only a few proven ways to integrate templates into an OO system.

12a) STL is NOT one of them. STL is high-template, low-OO.

12b) in java is an excellent way to combine them.


My first focus on the template+OO integration is the role of the actual type. See other posts on allocator and comparator. Only if you are already thoroughly familiar with has-a, then only you can understand how the actual type is used in OO and how it interacts with has-a.

A concrete template class could treat the actual type as an OO “component”, but I feel it's very different from a regular field.

c++class templates: container^other categories

I feel most introductory texts and most interview questions follow the “container” theme. There’s at least one field of type T. This prompted me to rethink the Usage, industry adoption and justification of c++ class templates.

Most well-known libraries define class templates. They don’t all follow that “theme”.

In enterprise application teams, however, out of MS I don’t see a lot of brand-new templates created from scratch. (Let’s not hypothesize why.) A lot of template class concretized; perhaps (presumably) some new templates created based on some proven designs, with low risk and low complexity. I do see some templates created in a local library, such as a MatrixDouble or a SmartPtr, but few.

Bottom line — you seldom create your own new class template. If you do, then I would venture to say the first template you /popularize/ is likely a container.

The class templates I created so far —

* matrix of any type like string or number, with user-defined size

* circular array

Template meta programming is deep and complex. However, if a template has no specialization, no non-type param, no nested template as a type param, no inheritance, then it’s manageable. I feel these can be meaningful, practical and useful class templates. My phone is useful without data plan, camera, browser, organizer and other bells and whistles.

specify a functor-object^functor-type

Sometimes [1] you plug in a functor object; sometimes [2] you plug in a functor type into a template.

In [2], I confirmed that concretized class’s would instantiate a functor object. In short, you specify functor TYPE only– instantiation is implicit. Note a template usually specifies a type param. A function type meets the requirement; a functor object doesn’t.

(I seldom see a template with a NDTTP like “int” — kind of wizardry.)

[1] In the first case you usually have a regular function, not a template

One use case of functor-object-passing (pbclone) is a STL algorithm like

 class myLess {/*....*/};

 std::sort(V.begin(), V.end(), myLess()); // which is short version of


 std::sort <vector ::iterator, // 1st concrete type
               myLess // 2nd concrete type
           > //now we have a concretized function. Below are 3 args:
   (V.begin(), V.end(), myLess()); // ctor args

In this case, the functor instantiation is fairly explicit.

concretized template class≠ordinary class

This topic is largely personal  curiosity, not needed for IV or project.

Many people say “use a concrete templ class just as an ordinary class” but nonono. A whale is a mammal, but not just another ordinary mammal. Concretized classes (i.e. concretized template class) differ from ordinary classes because

* when you declare a variable of the new type, your type must obey the “policy”
* a concrete template class’s behavior is specified in multiple places — the policy classes, the class of each template argument. A regular class’s behavior is specified in that class only. Look at the allocator param in a parametrized container.
* debugger for concrete templ classes is harder than ordinary classes
* casting is complicated
* when you plug in a functor type, the specialized template class’s instance instantiates a functor object. In short, you specify functor TYPE only — instantiation is implicit.
* a type involving templates interplays with ptr/ref in more complex ways than non-template types. (typedef often needed). When you add ptr (or ref) symbol to a non-template type, you just stick the qq(*) in the correct places. But how about qq[ map<char**, list*> & ] as a “first part” inside a parenthesis?

template-argument inference and binary_function

– function templates are often specialized without explicit template-argument, because compiler can infer from function arguments.
– However, class templates always need explicit template-argument.

Despite the name, unary_function (and binary_function) is an empty class template (actually struct template)
* without operator() declared ( — so You must subclass and furnish it in order to use it )
* that needs explicit type arg.

what can u say when seeing a function parameter type

If you see a function param like f(Animal myArg, …), what can you say about myArg’s type “Animal”?

* it can be a dummy-type declared for templates like the T in
* it can be a real class
* it can be a typedef
** underlying type could be a ptr
** underlying type could be a func ptr
** underlying type could be an array

We need a better understanding of typedef….

TYPE — different meanings in java vs c++

PRECISE meaning of Type differs between java and C++.

Java :
– any (even marker) interface,
– any class,
– any primitive….
is a type. We say “the declared type of the variable”.

c++ :
* any class, paramtrized or not
* primitive data type … is a type.
* typedef can declare new type names like aliases, but can’t create new types. Consider const_reverse_iterator.

java type bounds, c++ concepts, templates

If you have a c++ parametrized class C with whose T must have “operator>”, then java has a better solution —

class C

Now, if a parametrized function f(T input) with whose T must have “operator>”, i would guess java would ditch the generics and simply declare f(Comparable input).

In the general scenario, a template param T has constraints such as “having run() method”, “numeric”, “copyable”, “assignable”, “dereferenceable like a smart ptr”. In a /degenerate/ case, there’s no constraint — vector can take any type[1]. In another degenerate case, a template param can have so many constraints that the template class can take nothing but USPresident class — Better drop the template.

[1] actually vector requires T to be copyable.

Back to the constraints, c++ compilers actually check some of these constraints and won’t let you specialize a template with an incompatible type. Examples —

* if you specialize natural_log() with a non-numeric type, compiler breaks.
* if you specialize a sort() with a non-random-access iterator, …. compile time or runtime error? I think compiler is too dumb.
* ARM p343 — linker detects a non-comparable type specializing a sorting template.

After reading http://www.devx.com/SpecialReports/Article/38864, I feel c++concept (cconcept) resembles java type bounds of the form

Java interface is better. The constraints above usually translate to methods. In that case they can be implemented using interfaces, without generics. Occasionally, you can use something like

c++ : first thing in angle bracket

(Let’s exclude the obvious scenario of “template “. Instead, suppose we encounter an *instantiation* of an existing template.)

* First thing could be a simple, real type like int or Account
* First thing could be a dummy type like T or InputIterator. Note the type should be declared in an enclosing “template <class T…", so now we are inside a template definition, using the dummy type to instantiate *another* template. See [[essential c++]]
* first thing could be a typedef

Next, you realize you could also encounter a ptr/ref to the above. (This is why java generics are cleaner.)
* first thing could be a ptr to a typedef
* first thing could be a ptr to a dummy type?

Finally, a typedef can be a complex type involving dummy types and ptr/ref.

These make c++ template syntax/usage significantly messier and more complex than java generics.

"PREDICATE" = boolean-expression OR other meanings

In STL, the 2 types of predicates — filter vs the comparator — could cause major confusions to beginners learning the STL syntax details

predicate = any statement that evaluates an expression and returns a boolean.
predicate (xsl) = a filter
predicate = a proposition
predicate = an assertion

— contexts —
xpath?
sql where-clause? filter on list
matlab? filter on list