easing c++ to objective-c/cocoa bridging via metaprogramming? - c++

In a pure C++ world we can generate interfacing or glue code between different components or interfaces at compile time, using a combination of template-based compile-time and runtime-techniques (to e.g. mostly automatically marshall to/from calls using legacy types).
When having to interface C++ applications with Objective-C/Cocoa for GUI, system integration or IPC though, things become harder due to the less strict typing - yet often not more then a flat repitive interface layer is needed: thin bridging delegates have to be defined or conversion code to language bridging calls has to be written.
If you have to deal with interfaces of non-trivial size and want to avoid script-based code generation this quickly becomes cumbersome and is just a pain every time refactorings have to take place. Using a combination of (template) metaprogramming and the Objective-C runtime library, it should be possible to reduce the amount of code considerably...
Before i go to reinvent the wheel (and possibly waste time), does anyone know about techniques, best-practices or examples in that direction?
As for an example, lets say we need a delegate that supports this informal protocol:
- (NSString*)concatString:(NSString*)s1 withString:(NSString*)s2;
- (NSNumber*) indexOf:(CustomClass*)obj;
Instead of implementing an Obj-C class now that explicitly bridges to a C++-instance, i'd like to do something like this instead:
class CppObj {
ObjcDelegate m_del;
public:
CppObj() : m_del(this)
{
m_del.addHandler
<NSString* (NSString*, NSString*)>
("concatString", &CppObj::concat);
m_del.addHandler
<NSNumber* (CustomClass*)>
("indexOf", &CppObj::indexOf);
}
std::string concat(const std::string& s1, const std::string& s2) {
return s1.append(s2);
}
size_t indexOf(const ConvertedCustomClass& obj) {
return 42;
}
};
All that should be needed from the user to support additional types would be to specialize a conversion template function:
template<class To, class From> To convert(const From&);
template<>
NSString* convert<NSString*, std::string>(const std::string& s) {
// ...
}
// ...
The example above of course does ignore support for formal protocols etc. but should get the point across. Also, due to the type-information for Objc-runtime-types being mostly decayed into some-native-types or class-type i don't think the explicit specification of parameter and return types for the delegate-methods can be avoided.

I didn't find anything satisfactory and came up with a prototype that, given the following informal protocol:
- (NSString*)concatString:(NSString*)s1 withString:(NSString*)s2;
and this C++ code:
struct CppClass {
std::string concatStrings(const std::string& s1, const std::string& s2) const {
return s1+s2;
}
};
std::string concatStrings(const std::string& s1, const std::string& s2) {
return s1+s2;
}
allows creating and passing a delegate:
CppClass cpp;
og::ObjcClass objc("MyGlueClass");
objc.add_handler<NSString* (NSString*, NSString*)>
("concatString:withString:", &cpp, &CppClass::concatStrings);
// or using a free function:
objc.add_handler<NSString* (NSString*, NSString*)>
("concatString:withString:", &concatStrings);
[someInstance setDelegate:objc.get_instance()];
which can then be used:
NSString* result = [delegate concatString:#"abc" withString:#"def"];
assert([result compare:#"abcdef"] == NSOrderedSame);
Boost.Function objects can also be passed, which means Boost.Bind can easily be used as well.
While the basic idea works, this is still a prototype. I did a short blog post on the subject and the prototype source is available via bitbucket. Constructive input and ideas welcome.

Did you look at the wxWidgets library? I don't code in Objective-C, but at least the developers claim decent support for Cocoa/Objective-C. Which means, they have some mapping from C++ implemented somehow. The library's website is http://www.wxwidgets.org.

Related

Is it really a good technique to work with legacy code (with reinterpret_cast)?

Below code came from a post about C++ interview questions here. I've never known this technique :) (though it's claimed a good one :)). My questions are: In which situation do we need to use it? Do you often see it in your real production/legacy code?
Question:
Implement a method to get topSecretValue for any given Something* object. The method should be cross-platform compatible and not depend on sizeof (int, bool, string).
class Something {
Something() {
topSecretValue = 42;
}
bool somePublicBool;
int somePublicInt;
std::string somePublicString;
private:
int topSecretValue;
};
Answer:
Create another class which has all the members of Something in the same order, but has additional public method which returns the value. Your replica Something class should look like:
class SomethingReplica {
public:
int getTopSecretValue() { return topSecretValue; } // <-- new member function
bool somePublicBool;
int somePublicInt;
std::string somePublicString;
private:
int topSecretValue;
};
int main(int argc, const char * argv[]) {
Something a;
SomethingReplica* b = reinterpret_cast<SomethingReplica*>(&a);
std::cout << b->getTopSecretValue();
}
It’s important to avoid code like this in a final product, but it’s nevertheless a good technique when dealing with legacy code, as it can be used to extract intermediate calculation values from a library class. (Note: If it turns out that the alignment of the external library is mismatched to your code, you can resolve this using #pragma pack.)
You can do this without reinterpret_cast. There is a trick using templates and friends that is outlined in the following blog post that demonstrates the technique:
Access to private members. That's easy!
This is certainly safer than the interviewer's approach, since it eliminates human error in re-creating the class definition. Is this approach good at all, though? The given question has some incredibly artificial constraints that would rarely apply to a 'real' project. If it's a C++ project and you have access to the header file, why not just add a getter? If it's not a C++ project, why are you so constrained in your definition of the interop class?

Efficient configuration of class hierarchy at compile-time

This question is specifically about C++ architecture on embedded, hard real-time systems. This implies that large parts of the data-structures as well as the exact program-flow are given at compile-time, performance is important and a lot of code can be inlined. Solutions preferably use C++03 only, but C++11 inputs are also welcome.
I am looking for established design-patterns and solutions to the architectural problem where the same code-base should be re-used for several, closely related products, while some parts (e.g. the hardware-abstraction) will necessarily be different.
I will likely end up with a hierarchical structure of modules encapsulated in classes that might then look somehow like this, assuming 4 layers:
Product A Product B
Toplevel_A Toplevel_B (different for A and B, but with common parts)
Middle_generic Middle_generic (same for A and B)
Sub_generic Sub_generic (same for A and B)
Hardware_A Hardware_B (different for A and B)
Here, some classes inherit from a common base class (e.g. Toplevel_A from Toplevel_base) while others do not need to be specialized at all (e.g. Middle_generic).
Currently I can think of the following approaches:
(A): If this was a regular desktop-application, I would use virtual inheritance and create the instances at run-time, using e.g. an Abstract Factory.
Drawback: However the *_B classes will never be used in product A and hence the dereferencing of all the virtual function calls and members not linked to an address at run-time will lead to quite some overhead.
(B) Using template specialization as inheritance mechanism (e.g. CRTP)
template<class Derived>
class Toplevel { /* generic stuff ... */ };
class Toplevel_A : public Toplevel<Toplevel_A> { /* specific stuff ... */ };
Drawback: Hard to understand.
(C): Use different sets of matching files and let the build-scripts include the right one
// common/toplevel_base.h
class Toplevel_base { /* ... */ };
// product_A/toplevel.h
class Toplevel : Toplevel_base { /* ... */ };
// product_B/toplevel.h
class Toplevel : Toplevel_base { /* ... */ };
// build_script.A
compiler -Icommon -Iproduct_A
Drawback: Confusing, tricky to maintain and test.
(D): One big typedef (or #define) file
//typedef_A.h
typedef Toplevel_A Toplevel_to_be_used;
typedef Hardware_A Hardware_to_be_used;
// etc.
// sub_generic.h
class sub_generic {
Hardware_to_be_used the_hardware;
// etc.
};
Drawback: One file to be included everywhere and still the need of another mechnism to actually switch between different configurations.
(E): A similar, "Policy based" configuration, e.g.
template <class Policy>
class Toplevel {
Middle_generic<Policy> the_middle;
// ...
};
// ...
template <class Policy>
class Sub_generic {
class Policy::Hardware_to_be_used the_hardware;
// ...
};
// used as
class Policy_A {
typedef Hardware_A Hardware_to_be_used;
};
Toplevel<Policy_A> the_toplevel;
Drawback: Everything is a template now; a lot of code needs to be re-compiled every time.
(F): Compiler switch and preprocessor
// sub_generic.h
class Sub_generic {
#if PRODUCT_IS_A
Hardware_A _hardware;
#endif
#if PRODUCT_IS_B
Hardware_B _hardware;
#endif
};
Drawback: Brrr..., only if all else fails.
Is there any (other) established design-pattern or a better solution to this problem, such that the compiler can statically allocate as many objects as possible and inline large parts of the code, knowing which product is being built and which classes are going to be used?
I'd go for A. Until it's PROVEN that this is not good enough, go for the same decisions as for desktop (well, of course, allocating several kilobytes on the stack, or using global variables that are many megabytes large may be "obvious" that it's not going to work). Yes, there is SOME overhead in calling virtual functions, but I would go for the most obvious and natural C++ solution FIRST, then redesign if it's not "good enough" (obviously, try to determine performance and such early on, and use tools like a sampling profiler to determine where you are spending time, rather than "guessing" - humans are proven pretty poor guessers).
I'd then move to option B if A is proven to not work. This is indeed not entirely obvious, but it is, roughly, how LLVM/Clang solves this problem for combinations of hardware and OS, see:
https://github.com/llvm-mirror/clang/blob/master/lib/Basic/Targets.cpp
First I would like to point out that you basically answered your own question in the question :-)
Next I would like to point out that in C++
the exact program-flow are given at compile-time, performance is
important and a lot of code can be inlined
is called templates. The other approaches that leverage language features as opposed to build system features will serve only as a logical way of structuring the code in your project to the benefit of developers.
Further, as noted in other answers C is more common for hard real-time systems than are C++, and in C it is customary to rely on MACROS to make this kind of optimization at compile time.
Finally, you have noted under your B solution above that template specialization is hard to understand. I would argue that this depends on how you do it and also on how much experience your team has on C++/templates. I find many "template ridden" projects to be extremely hard to read and the error messages they produce to be unholy at best, but I still manage to make effective use of templates in my own projects because I respect the KISS principle while doing it.
So my answer to you is, go with B or ditch C++ for C
I understand that you have two important requirements :
Data types are known at compile time
Program-flow is known at compile time
The CRTP wouldn't really address the problem you are trying to solve as it would allow the HardwareLayer to call methods on the Sub_generic, Middle_generic or TopLevel and I don't believe it is what you are looking for.
Both of your requirements can be met using the Trait pattern (another reference). Here is an example proving both requirements are met. First, we define empty shells representing two Hardwares you might want to support.
class Hardware_A {};
class Hardware_B {};
Then let's consider a class that describes a general case which corresponds to Hardware_A.
template <typename Hardware>
class HardwareLayer
{
public:
typedef long int64_t;
static int64_t getCPUSerialNumber() {return 0;}
};
Now let's see a specialization for Hardware_B :
template <>
class HardwareLayer<Hardware_B>
{
public:
typedef int int64_t;
static int64_t getCPUSerialNumber() {return 1;}
};
Now, here is a usage example within the Sub_generic layer :
template <typename Hardware>
class Sub_generic
{
public:
typedef HardwareLayer<Hardware> HwLayer;
typedef typename HwLayer::int64_t int64_t;
int64_t doSomething() {return HwLayer::getCPUSerialNumber();}
};
And finally, a short main that executes both code paths and use both data types :
int main(int argc, const char * argv[]) {
std::cout << "Hardware_A : " << Sub_generic<Hardware_A>().doSomething() << std::endl;
std::cout << "Hardware_B : " << Sub_generic<Hardware_B>().doSomething() << std::endl;
}
Now if your HardwareLayer needs to maintain state, here is another way to implement the HardLayer and Sub_generic layer classes.
template <typename Hardware>
class HardwareLayer
{
public:
typedef long hwint64_t;
hwint64_t getCPUSerialNumber() {return mySerial;}
private:
hwint64_t mySerial = 0;
};
template <>
class HardwareLayer<Hardware_B>
{
public:
typedef int hwint64_t;
hwint64_t getCPUSerialNumber() {return mySerial;}
private:
hwint64_t mySerial = 1;
};
template <typename Hardware>
class Sub_generic : public HardwareLayer<Hardware>
{
public:
typedef HardwareLayer<Hardware> HwLayer;
typedef typename HwLayer::hwint64_t hwint64_t;
hwint64_t doSomething() {return HwLayer::getCPUSerialNumber();}
};
And here is a last variant where only the Sub_generic implementation changes :
template <typename Hardware>
class Sub_generic
{
public:
typedef HardwareLayer<Hardware> HwLayer;
typedef typename HwLayer::hwint64_t hwint64_t;
hwint64_t doSomething() {return hw.getCPUSerialNumber();}
private:
HwLayer hw;
};
On a similar train of thought to F, you could just have a directory layout like this:
Hardware/
common/inc/hardware.h
hardware1/src/hardware.cpp
hardware2/src/hardware.cpp
Simplify the interface to only assume a single hardware exists:
// sub_generic.h
class Sub_generic {
Hardware _hardware;
};
And then only compile the folder that contains the .cpp files for the hardware for that platform.
The benefits to this approach are:
It's simple to understand whats happening and to add a hardware3
hardware.h still serves as your API
It takes away the abstraction from the compiler (for your speed concerns)
Compiler 1 doesn't need to compile hardware2.cpp or hardware3.cpp which may contain things Compiler 1 can't do (like inline assembly, or some other specific Compiler 2 thing)
hardware3 might be much more complicated for some reason you haven't considered yet.. so giving it a whole directory structure encapsulates it.
Since this is for a hard real time embedded system, usually you would go for a C type of solution not c++.
With modern compilers I'd say that the overhead of c++ is not that great, so it's not entirely a matter of performance, but embedded systems tend to prefer c instead of c++.
What you are trying to build would resemble a classic device drivers library (like the one for ftdi chips).
The approach there would be (since it's written in C) something similar to your F, but with no compile time options - you would specialize the code, at runtime, based on somethig like PID, VID, SN, etc...
Now if you what to use c++ for this, templates should probably be your last option (code readability usually ranks higher than any advantage templates bring to the table). So you would probably go for something similar to A: a basic class inheritance scheme, but no particularly fancy design pattern is required.
Hope this helps...
I am going to assume that these classes only need to be created a single time, and that their instances persist throughout the entire program run time.
In this case I would recommend using the Object Factory pattern since the factory will only get run one time to create the class. From that point on the specialized classes are all a known type.

How to read through types of a struct in C/C++

I am trying to find the "types" of any given variables in different structs and be able to read them. (keep in mind this is psuedo code)
For Example:
#include "stream.h" //a custom stream reader class I made
typedef unsigned char BYTE;
/***** SERIES OF DIFFERENT STRUCTS ******/
struct asset
{
char *name;
int size;
BYTE *data;
};
struct asset2
{
char *lang;
char *entry;
};
/*****************************************/
void readAsset( Enumerable<struct> &istruct)
{
foreach( object o in istruct )
{
switch( o )
{
case int:
&o = _stream->ReadInt32();
break;
case char:
&o = _stream->ReadChar();
break;
case *:
&o = _stream->ReadInt32();
break;
default: break;
}
}
}
I want it to be able to do the following:
asset a1;
asset2 a2;
readAsset( a1 );
readAsset( a2 );
and pass all the info from the file to a1 and a2.
I was wondering if there was a way in C/C++ to get the type of the data from any object in the struct then read based on that? is it possible with complex enums? Sorry for the bad code but I wanted it to be easier to understand what I'm trying to do.
Additional Info:
_stream is a pointer to a Stream class I made similar to Stream Reader in .Net It reads data from a file and advances it's position based on how big of data it was read.
I'll be happy to re-phrase if you don't understand what I'm asking.
There is no way to iterate through the members of a structure without listing them all out.
You can iterate through something like a structure at compile time using ::std::tuple in C++11.
You also can't really switch on type in that fashion. You can do it, but the way you do it is to have several functions with the same name that each take a different parameter type. Something like:
void doRead(StreamType &stream, int &data)
{
data = stream.readInt32();
}
void doRead(StreamType &stream, char &data)
{
data = stream.readChar();
}
// etc...
Then you just call doRead with your structure member and poof the compiler magically picks the right one based on the type.
In C++, the way to solve the problem you're solving here is a serialization library. If you have control of both the format written and the format read, you can use something like protobuf or boost::serialization to do this relatively easily without having to write a lot of your own code.
Additionally, a couple of issues with your code. Do not use a leading _ character in identifiers. Identifiers with a leading _ are reserved for use by the compiler or standard library implementation. Many compilers have special keywords that are compiler specific language extensions that start with an _ character. Using identifiers with a leading _ character may result in your code mysteriously failing to compile with all kinds of strange inscrutable errors in some environments.
You can get something like a struct that is enumerable at compile time. But it's ugly:
#include <tuple>
#include <string>
#include <vector>
#include <type_traits>
class asset : public ::std::tuple< ::std::string, ::std::vector<BYTE> >
{
public:
::std::string &name() { return ::std::get<0>(*this); }
const ::std::string &name() const { return ::std::get<0>(*this); }
::std::vector<BYTE> &data() { return ::std::get<1>(*this); }
const ::std::vector<BYTE> &data() const { return ::std::get<1>(*this); }
};
void writeToStream(Stream *out, const ::std::string &field)
{
out->writeString(field);
}
void writeToStream(Stream *out, const ::std::vector<BYTE> &field)
{
out->writeInt(field.size());
out->writeRaw(field.data(), field.size());
}
template <unsigned int fnum, typename... T>
typename ::std::enable_if< (fnum < sizeof...(T)), void >::type
writeToStream_n(Stream *out, const::std::tuple<T...> &field)
{
writeToStream(out, ::std::get<fnum>(field));
writeToStream_n<fnum+1, T...>(out, field);
}
template <unsigned int fnum, typename... T>
typename ::std::enable_if< (fnum >= sizeof...(T)) >::type
writeToStream_n(Stream *, const::std::tuple<T...> &)
{
}
template <typename... Tp>
void writeToStream(Stream *out, const ::std::tuple<Tp...> &composite)
{
writeToStream_n<0, Tp...>(out, composite);
}
void foo(Stream *out, const asset &a)
{
writeToStream(out, a);
}
Notice that there is no explicit writeToStream for the asset type. The compiler will write it at runtime by unpacking the ::std::tuple it's derived from and writing out each individual field.
Also, if you have bare pointers, you're writing poor C++. Please write idiomatic, good C++ if you're going to write C++. This whole thing you want to do with runtime reflection is just not the way to do things.
That's the reason I converted your char *name to a ::std::string and your size delimited BYTE array represented by your size and data fields into a ::std::vector. Using those types is the idiomatically correct way to write C++. Using bare pointers the way you were is not. Additionally, having two fields that have strongly related values (the data and size) fields that have no behavior or any other indication that they're associated would make it hard even for a compiler that does introspection at runtime to figure out the right thing to do. It can't know how big the BYTE array being pointed to by data is, and it can't know about your decision to encode this in size.
What you're asking for is something called Reflection - which is:
the ability of a computer program to examine
and modify the structure and behavior (specifically the values,
meta-data, properties and functions) of an object at runtime.
C++ doesn't have that "natively".
What I mean is - there have been some attempts at introducing some aspects of it - with varied degrees of success - which have produced some aspects of Reflection, but not "full" Reflection itself as you will get in a language like Ruby or so.
However, if you are feeling adventurous, you can try a Reflection library called Reflectabit:
To see if it might be worthwhile (which it might be considering your code), it is referenced here - which has quite a bit of examples on how to use the API:
http://www.altdevblogaday.com/2011/09/25/reflection-in-c-part-1-introduction/
Good luck!
The usual pattern in C++ is not to try and figure out what the members of the type are, but rather provide an operator, implemented by the implementor of the type, that is able to serialize/deserialize to disk.
You can take a look at, for example, the boost::serialize library. The usage is not too complex, you need to provide a function that lists your members in some order and then the library will take it from there and implement serialization to different formats.

How to convert a string to a class name [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++: instantiate class from name?
For example, if I have
string s = "myObject";
So how can I use that String s to make this one?
return new myObject();
I tried this one but it's quite silly and it's wrong
return new s();
Thank you
You can create a simple factory and register the classes you want to be able to construct. This is a very light-weight sort-of reflection.
#include <map>
#include <string>
template <class T> void* constructor() { return (void*)new T(); }
struct factory
{
typedef void*(*constructor_t)();
typedef std::map<std::string, constructor_t> map_type;
map_type m_classes;
template <class T>
void register_class(std::string const& n)
{ m_classes.insert(std::make_pair(n, &constructor<T>)); }
void* construct(std::string const& n)
{
map_type::iterator i = m_classes.find(n);
if (i == m_classes.end()) return 0; // or throw or whatever you want
return i->second();
}
};
factory g_factory;
#define REGISTER_CLASS(n) g_factory.register_class<n>(#n)
int main()
{
using namespace std;
REGISTER_CLASS(string);
std::string* s = (std::string*)g_factory.construct("string");
printf("s = '%s'\n", s->c_str());
*s = "foobar";
printf("s = '%s'\n", s->c_str());
return 0;
}
What you want is called virtual constructor (pattern). The availability of this feature in a language is not necessarily coupled to the language being interpreted or managed by a VM - it depends on how (and if at all) the information about types existing in a program (or library) is available at run time. This is not the case in "naked" C++ - but it can be implemented, as shown by Arvid, for example. The problem is that there is no standardized implementation of this feature, so everybody keeps re-inventing this again and again. To certain extent COM or it's platform independent counterpart XPCOM "standardize" this at component level.
You cannot do that in c++, by design. In c++, there is a clear distinction between a type and an object, which are two very different entities of the language. You can thus only instantiate a type and get back an object, and decide to do so at compile time (c++ does not provide any kind of reflection system unlike c# or java).
However, you can use a factory / registry for the objects you want to instantiate that way.
You'll need Reflection to do that. But C++ AFAIK doesn't support reflection.
Interestingly QT C++ Supports some kinda reflection. Look at the C# section for how its done there, and Javascript has one function to do this. Its called eval()
It's not possible to do this with C++ since the code run on it's own. Only interpreted languages, such as PHP, or programs that are run through interpreters allows this kind of feature.

Where do you find templates useful?

At my workplace, we tend to use iostream, string, vector, map, and the odd algorithm or two. We haven't actually found many situations where template techniques were a best solution to a problem.
What I am looking for here are ideas, and optionally sample code that shows how you used a template technique to create a new solution to a problem that you encountered in real life.
As a bribe, expect an up vote for your answer.
General info on templates:
Templates are useful anytime you need to use the same code but operating on different data types, where the types are known at compile time. And also when you have any kind of container object.
A very common usage is for just about every type of data structure. For example: Singly linked lists, doubly linked lists, trees, tries, hashtables, ...
Another very common usage is for sorting algorithms.
One of the main advantages of using templates is that you can remove code duplication. Code duplication is one of the biggest things you should avoid when programming.
You could implement a function Max as both a macro or a template, but the template implementation would be type safe and therefore better.
And now onto the cool stuff:
Also see template metaprogramming, which is a way of pre-evaluating code at compile-time rather than at run-time. Template metaprogramming has only immutable variables, and therefore its variables cannot change. Because of this template metaprogramming can be seen as a type of functional programming.
Check out this example of template metaprogramming from Wikipedia. It shows how templates can be used to execute code at compile time. Therefore at runtime you have a pre-calculated constant.
template <int N>
struct Factorial
{
enum { value = N * Factorial<N - 1>::value };
};
template <>
struct Factorial<0>
{
enum { value = 1 };
};
// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
int x = Factorial<4>::value; // == 24
int y = Factorial<0>::value; // == 1
}
I've used a lot of template code, mostly in Boost and the STL, but I've seldom had a need to write any.
One of the exceptions, a few years ago, was in a program that manipulated Windows PE-format EXE files. The company wanted to add 64-bit support, but the ExeFile class that I'd written to handle the files only worked with 32-bit ones. The code required to manipulate the 64-bit version was essentially identical, but it needed to use a different address type (64-bit instead of 32-bit), which caused two other data structures to be different as well.
Based on the STL's use of a single template to support both std::string and std::wstring, I decided to try making ExeFile a template, with the differing data structures and the address type as parameters. There were two places where I still had to use #ifdef WIN64 lines (slightly different processing requirements), but it wasn't really difficult to do. We've got full 32- and 64-bit support in that program now, and using the template means that every modification we've done since automatically applies to both versions.
One place that I do use templates to create my own code is to implement policy classes as described by Andrei Alexandrescu in Modern C++ Design. At present I'm working on a project that includes a set of classes that interact with BEA\h\h\h Oracle's Tuxedo TP monitor.
One facility that Tuxedo provides is transactional persistant queues, so I have a class TpQueue that interacts with the queue:
class TpQueue {
public:
void enqueue(...)
void dequeue(...)
...
}
However as the queue is transactional I need to decide what transaction behaviour I want; this could be done seperately outside of the TpQueue class but I think it's more explicit and less error prone if each TpQueue instance has its own policy on transactions. So I have a set of TransactionPolicy classes such as:
class OwnTransaction {
public:
begin(...) // Suspend any open transaction and start a new one
commit(..) // Commit my transaction and resume any suspended one
abort(...)
}
class SharedTransaction {
public:
begin(...) // Join the currently active transaction or start a new one if there isn't one
...
}
And the TpQueue class gets re-written as
template <typename TXNPOLICY = SharedTransaction>
class TpQueue : public TXNPOLICY {
...
}
So inside TpQueue I can call begin(), abort(), commit() as needed but can change the behaviour based on the way I declare the instance:
TpQueue<SharedTransaction> queue1 ;
TpQueue<OwnTransaction> queue2 ;
I used templates (with the help of Boost.Fusion) to achieve type-safe integers for a hypergraph library that I was developing. I have a (hyper)edge ID and a vertex ID both of which are integers. With templates, vertex and hyperedge IDs became different types and using one when the other was expected generated a compile-time error. Saved me a lot of headache that I'd otherwise have with run-time debugging.
Here's one example from a real project. I have getter functions like this:
bool getValue(wxString key, wxString& value);
bool getValue(wxString key, int& value);
bool getValue(wxString key, double& value);
bool getValue(wxString key, bool& value);
bool getValue(wxString key, StorageGranularity& value);
bool getValue(wxString key, std::vector<wxString>& value);
And then a variant with the 'default' value. It returns the value for key if it exists, or default value if it doesn't. Template saved me from having to create 6 new functions myself.
template <typename T>
T get(wxString key, const T& defaultValue)
{
T temp;
if (getValue(key, temp))
return temp;
else
return defaultValue;
}
Templates I regulary consume are a multitude of container classes, boost smart pointers, scopeguards, a few STL algorithms.
Scenarios in which I have written templates:
custom containers
memory management, implementing type safety and CTor/DTor invocation on top of void * allocators
common implementation for overloads wiht different types, e.g.
bool ContainsNan(float * , int)
bool ContainsNan(double *, int)
which both just call a (local, hidden) helper function
template <typename T>
bool ContainsNanT<T>(T * values, int len) { ... actual code goes here } ;
Specific algorithms that are independent of the type, as long as the type has certain properties, e.g. binary serialization.
template <typename T>
void BinStream::Serialize(T & value) { ... }
// to make a type serializable, you need to implement
void SerializeElement(BinStream & strean, Foo & element);
void DeserializeElement(BinStream & stream, Foo & element)
Unlike virtual functions, templates allow more optimizations to take place.
Generally, templates allow to implement one concept or algorithm for a multitude of types, and have the differences resolved already at compile time.
We use COM and accept a pointer to an object that can either implement another interface directly or via [IServiceProvider](http://msdn.microsoft.com/en-us/library/cc678965(VS.85).aspx) this prompted me to create this helper cast-like function.
// Get interface either via QueryInterface of via QueryService
template <class IFace>
CComPtr<IFace> GetIFace(IUnknown* unk)
{
CComQIPtr<IFace> ret = unk; // Try QueryInterface
if (ret == NULL) { // Fallback to QueryService
if(CComQIPtr<IServiceProvider> ser = unk)
ser->QueryService(__uuidof(IFace), __uuidof(IFace), (void**)&ret);
}
return ret;
}
I use templates to specify function object types. I often write code that takes a function object as an argument -- a function to integrate, a function to optimize, etc. -- and I find templates more convenient than inheritance. So my code receiving a function object -- such as an integrator or optimizer -- has a template parameter to specify the kind of function object it operates on.
The obvious reasons (like preventing code-duplication by operating on different data types) aside, there is this really cool pattern that's called policy based design. I have asked a question about policies vs strategies.
Now, what's so nifty about this feature. Consider you are writing an interface for others to use. You know that your interface will be used, because it is a module in its own domain. But you don't know yet how people are going to use it. Policy-based design strengthens your code for future reuse; it makes you independent of data types a particular implementation relies on. The code is just "slurped in". :-)
Traits are per se a wonderful idea. They can attach particular behaviour, data and typedata to a model. Traits allow complete parameterization of all of these three fields. And the best of it, it's a very good way to make code reusable.
I once saw the following code:
void doSomethingGeneric1(SomeClass * c, SomeClass & d)
{
// three lines of code
callFunctionGeneric1(c) ;
// three lines of code
}
repeated ten times:
void doSomethingGeneric2(SomeClass * c, SomeClass & d)
void doSomethingGeneric3(SomeClass * c, SomeClass & d)
void doSomethingGeneric4(SomeClass * c, SomeClass & d)
// Etc
Each function having the same 6 lines of code copy/pasted, and each time calling another function callFunctionGenericX with the same number suffix.
There were no way to refactor the whole thing altogether. So I kept the refactoring local.
I changed the code this way (from memory):
template<typename T>
void doSomethingGenericAnything(SomeClass * c, SomeClass & d, T t)
{
// three lines of code
t(c) ;
// three lines of code
}
And modified the existing code with:
void doSomethingGeneric1(SomeClass * c, SomeClass & d)
{
doSomethingGenericAnything(c, d, callFunctionGeneric1) ;
}
void doSomethingGeneric2(SomeClass * c, SomeClass & d)
{
doSomethingGenericAnything(c, d, callFunctionGeneric2) ;
}
Etc.
This is somewhat highjacking the template thing, but in the end, I guess it's better than play with typedefed function pointers or using macros.
I personally have used the Curiously Recurring Template Pattern as a means of enforcing some form of top-down design and bottom-up implementation. An example would be a specification for a generic handler where certain requirements on both form and interface are enforced on derived types at compile time. It looks something like this:
template <class Derived>
struct handler_base : Derived {
void pre_call() {
// do any universal pre_call handling here
static_cast<Derived *>(this)->pre_call();
};
void post_call(typename Derived::result_type & result) {
static_cast<Derived *>(this)->post_call(result);
// do any universal post_call handling here
};
typename Derived::result_type
operator() (typename Derived::arg_pack const & args) {
pre_call();
typename Derived::result_type temp = static_cast<Derived *>(this)->eval(args);
post_call(temp);
return temp;
};
};
Something like this can be used then to make sure your handlers derive from this template and enforce top-down design and then allow for bottom-up customization:
struct my_handler : handler_base<my_handler> {
typedef int result_type; // required to compile
typedef tuple<int, int> arg_pack; // required to compile
void pre_call(); // required to compile
void post_call(int &); // required to compile
int eval(arg_pack const &); // required to compile
};
This then allows you to have generic polymorphic functions that deal with only handler_base<> derived types:
template <class T, class Arg0, class Arg1>
typename T::result_type
invoke(handler_base<T> & handler, Arg0 const & arg0, Arg1 const & arg1) {
return handler(make_tuple(arg0, arg1));
};
It's already been mentioned that you can use templates as policy classes to do something. I use this a lot.
I also use them, with the help of property maps (see boost site for more information on this), in order to access data in a generic way. This gives the opportunity to change the way you store data, without ever having to change the way you retrieve it.