Let's say I have a type of lookup table which I can build for a given integer:
class FooLookupTable {
...
public:
FooLookupTable(int radix) {
...
}
};
Then there's a class whose template parameter is that same integer, and whose constructor initializes a member instance of this lookup table:
template <int radix> class Foo {
...
private:
FooLookupTable table;
public:
Foo () : FooLookupTable (radix) {
...
}
};
Throughout my code I instantiate these with various values of radix:
int main() {
...
Foo<1> myFoo;
Foo<1> yourFoo;
Foo<10> theirFoo;
...
}
This works and doesn't create any hairy threading or API issues. But it's not sharing the radix table for 1 between myFoo
and yourFoo
. I could hardcode a dependency on an assumed thread library, and build a global map that's filled on-demand. But my question is:
"In the modern C++11 world, is there a clean way designing a library for Foo which does not have dependencies outside of the standard libraries?"
I thought of using a static member for this, since each separate instantiation of a template class creates only one static member variable. But this brings up the question of who is responsible for declaring the space for the static member and whoever does so has to "know the right way to initialize it":
FooLookupTable Foo<1>::table (1);
FooLookupTable Foo<10>::table (10);
int main() {
...
Foo<1> myFoo;
Foo<1> yourFoo;
Foo<10> theirFoo;
...
}
Reading what's written on the subject like " C++ Static member initalization (template fun inside) " doesn't seem to turn up much hope...unless I'm missing something. Also, what would happen if Foo
instances themselves were static? :-/
static members of templates won't work well across APIs if you want to ensure all instantiations of Foo<1> share the same table. This is because, going across module boundaries, if module A creates Foo<1> and module B creates Foo<1>, it will duplicate the static members.
I think your best bet is to map those integers to their corresponding tables at runtime.
As a practical answer, no, not yet. You need critical sections/mutual exclusion for your table if you want thread safety (unless you can manage to make a shared container that is thread safe and lock-free with no third party dependencies) and there's nothing out of the box in C++11 that's implemented yet (at least in popular compilers) to give you cross-platform concurrency AFAIK.
In the future, C++11's concurrency features will support mutexes and atomics out of the box, but popular compilers haven't implemented this feature yet to my knowledge.
First, there's a standard thread library in C++11 you can rely on according to your own definition.
Then, you should mention that what you need as name: it's a singleton.
Finally, there's a way in C++11. The language is aware of threads, and as such, static variable initialization is thread safe:
EDIT:
You have mentioned a few fair points in the comments. Here is an answer better for your needs, I hope. Actually, the fact that FooLookup create templated foos is not useful to solve the problem. It confused me a bit, you don't need any templates for this.
EDIT 2
Made the function thread safe. My bad. It seems my first solution may be better for you after all. There is a solution without
<mutex>
if you know (at compilation time) the list of the radixes for which you want to create a lookup table.