Map with comparable key types - c++

Lately I started working on the implementation of a graph based database system. However I ran into a little problem.
The vertices in the graph are allowed to contain properties, of any type of comparable type. I was thinking about creating a map for these, as the keys are always string based. However I don't want to be bothered at all by the actually type, the only thing I want to do is compare them and still maintain safety checks. How would I go around doing so?
As I first approach I was thinking about using boost, however it'll still give me the headache of doing some manual type checking, which I absolutely do not want to do.
In Java I would do something like this, however I'm not used with these kind of things in C++.
map<String, ? extends comparable>
The reason for this is that a property can literally be any comparable type.

Not the actual answer but a requested example:
I'm used to create templates like that:
SomeClass.h:
#guards etc
template<class T> //or whatever you need
class SomeClass {
public:
SomeClass();
T content();
private:
T m_content;
}
SomeClass.cpp:
#include "SomeClass.h"
template<class T>
SomeClass::SomeClass(){
m_content = (T) 0;
}
template<class T>
T SomeClass::content(){
return T;
}
#include "SomeClass_Specializations.h"
SomeClass_Specializations.h:
#guards etc
#include "SomeClass.h"
#include "MyMagicUint.h"
//only types that behave like unsigned int may be added!
template class SomeClass<unsigned short>;
template class SomeClass<unsigned int>;
template class SomeClass<unsigned long>;
template class SomeClass<MyMagicUint>;
If you do it like that, you can specialize a long list of some common comparable types and write a comment in which you describe what other people are allowed to add to that list (in my example, unsigned int like types for some reason).
As a result, only those which are specialized here will work (since otherwise the implementation is missing), you probably have covered most of them and in the rare cases that somebody needs another specialization, he simply adds it to the list.
In the end, doing is as strict as that might not be needed, since it won't compile anyway if some forbidden action is performed, like using the <-operator when it's not defined for that type, but if you want that strict control, you can do it like that. Of course this hasn't got the dynamic control of ? extends ..., but it has control at least. Another advantage is that you can implement the code in a CPP file as usual, instead of having to put everything in the header as required for a dynamic template, that's mostly why it is my standard.
You could of course simply write the content of the specialization file directly at the bottom of the CPP instead of including another header, but I think that the specialization header is more elegant, informing prospective users what is allowed and giving them the option to add to it without taking a look at the implementation.

Related

Create an alias from one type to another

I'm writing some kind of DI container in c++ and I'm curious if it's possible to create aliases from one type to another in modern c++.
What I basicly want to do is to be able to call implementation constructor by it's aliased interface. Like so:
di::Register<Interface, Impl>();
di::Resolve<Interface>(); // -> Impl should be resolved
The problem is that I've not been able to find the way to alias Interface and Impl in compile time so far. I can do this using RTTI but I really don't want to use it. Is it possible at all?
By looking at the interface of your code, if you have a global state (which I don't actively recommend) you should get away with that:
using type_id_t = void(*)();
template<typename> void type_id() {}
struct di {
using create_function_t = void*(*)();
static std::unordered_map<type_id_t, create_function_t> types;
template<typename I, typename T>
static void Register() {
types.emplace(type_id<I>, []{
return static_cast<void*>(
static_cast<I*>(new T)
);
});
}
template<typename I>
static std::unique_ptr<I> Resolve() {
return std::unique_ptr<I>{static_cast<I*>(types[type_id<I>]())};
}
};
Live example
The problem is that I've not been able to find the way to alias Interface and Impl in compile time so far. I can do this using RTTI but I really don't want to use it. Is it possible at all?
There is a trick you can use to do this, assuming I understood your goal correctly. It won't look as nice as what you have there:
http://stackoverflow.com/questions/4790721/c-type-registration-at-compile-time-trick
This trick was attributed to Matt Calabrese, he described it in a Boostcon talk in like 2011.
To the best of my knowledge this trick is standards-conforming, but you must be very careful -- if you do start the registration in some header files and then continue it in some CPP files you may cause an ODR violation if you are careless.
I think you would end up with some macro like
REGISTER_PAIR( interface, impl );
and then you would have some type-alias, e.g.
get_registered_impl_t<interface>
which resolves to impl.
In the example they show how to make a list of types that is accumulated over time. In your case it would be a list of type-level "pairs" and you could search it by doing linear scan. You could try to use a fancy compile-time map data structure, but in most cases its pointless since linear scan will be fast enough, and also, the length of the list you can make is bounded by the maximum template instantiation depth of your compiler, which is typically like 100 or 200 or something. If you need larger lists there are some tricks you can use but I won't detail here.

Semantics of template specialization or separate functions

I am creating a C++ wrapper around the C library libnetfilter_conntrack, which uses the function nfct_set_attr(...). It takes an enum that defines the type of the attribute to set, along with a void* to pass in the data (which is different depending on the attribute). Since this is C++ I want to make it type-safe, so I need separate functions for each attribute type. To aid compatibility however, I created an enum class that defines all the attribute types available from libnetfilter_conntrack.
My original idea was to create templated set_attr(...) functions that take a template depending on the attribute that needs setting. For example:
template<attr_type, typename T> void set_attr(T); // designed to fail
template<> void set_attr<orig_ipv4_src, unsigned long>(unsigned long ip) {};
This approach has the advantage of directly linking the enum class definitions to the functions, which might make the logic slightly clearer. But I thought of another potential option, to use separate functions for each attribute:
void set_orig_ipv4_src(unsigned long ip) {};
Inside the function the enum class will be used anyway (to invoke the underlying C routine), so those definitions will still exist.
Which of the two methods above makes more sense? Are there any inherent problems using the template version? Performance issues?
The template approach as written does have a problem. Consider:
long ip = get_ip();
set_attr<orig_ipv4_src>(ip);
This code does not compile. Even though longs can be converted into unsigned longs, we wind up back in the generic template which presumably contains static_assert(false).
There is a way to fix this:
template<attrt ATTR>
struct attr_info {
typedef void argtype;
};
template<>
struct attr_info<orig_ipv4_src> {
typedef unsigned long argtype;
};
// etc.
template<attrt ATTR>
void set_attr(attr_info<ATTR>::argtype arg) {
// set the attr
}
This will do type promotion nicely. It will also let you get at this information in other ways if you want.
Still, for all its prettiness, I'm not sure this approach has any practical advantages over separate functions. That is, I'm not sure the things this enables are things anyone will ever want to do. And it will take more work for someone new to the project to understand.
I would propose looking through the old c code and seeing if anyone ever invokes this function with a non-literal first parameter. If so, make sure what they're doing is possible in the new system. If not, probably go with separate functions.

Static CRTP class without knowing derived type?

Given the following, working code.
#include <iostream>
template<class Detail>
class AbstractLogger
{
public:
static void log(const char* str) {
Detail::log_detailled(str);
}
};
class Logger : public AbstractLogger<Logger>
{
public:
static void log_detailled(const char* str) {
std::cerr << str << std::endl;
}
};
int main(void)
{
AbstractLogger<Logger>::log("main function running!");
return 0;
}
Now, I want to put AbstractLogger into a library, and let the library user define his own logger, like the Logger class here. This has one drawback: AbstractLogger<Logger> can not be used inside the library, since the library can not know Logger.
Notes:
Please no virtual functions or questions why not. Also, I am aware of the similar problem that "static virtual" members are invalid. Maybe, there is a workaround in CRTP :)
C++11 will be interesting, however, I need "usual" C++.
If what you mean is that you want to have a library that uses this as a logging mechanism without knowing the exact instantiating type, I would advice against it.
The only way of doing it while meeting your other requirements (i.e. no virtual functions) is that all your functions/types in the library that need to log are converted into templates that take the Logger type. The net result is that most of your interface becomes a template (although you can probably move a good amount of the implementation to non-templated code, it will make your life much harder than needed, and it will still generate a much larger binary).
If your concern with virtual functions is performance, then you should reconsider your approach and the problems it brings. In particular, logging is expensive. Most logging libraries tackle it by optimizing the non-logging case (by means of macros that avoid calling the logger if the log level/group/... are not enabled), but still leave dynamic dispatch for the actual writting. The cost of the dynamic dispatch is negligible compared with the cost of writing to the console, or a file, or even with the cost of generating the message that will be logged (I am assuming that you not only log literal strings)
The usual approach is to code against a concept, while providing helpers so that users may easily produce types that satisfy one or more of those concepts. As an example, something like boost::iterator_facade is a CRTP helper that makes it easier for a user to write an iterator. Then, that iterator can be used anywhere an iterator is accepted -- for instance in the range constructor of std::vector. Notice how that particular constructor has no foreknowledge of the user-defined type.
In your case, AbstractLogger would be the CRTP helper. The missing piece would be to define e.g. a logger concept. As a result, notice that everything that needs a logger either needs to be implemented as a template or you need a type-erasing container to hold arbitrary loggers.
Concept checks (like those provided by Boost) are convenient for this kind of programming, since they allow to represent a concept with actual code.
Template classes can't be 'put in a library' since they are instantiated by the compiler as specializations of their template parameters.
You may put parameter independent stuff used in the template implementation into a library though.

STL Metaprogramming - which types of my template class have been created at compile time?

First the apologies, i'm not sure if my question title even accuratly explains what I'm asking - I've had a look through google, but i'm not sure which terms I need in my search query, so the answer may be out there (or even on StackOverflow) already.
I have a templated class, which basically looks like the following - it uses the Singleton pattern, hence everything is static, I'm not looking for comments on why I'm storing the keys in a set and using strings etc, unless it actually provides a solution. There's a bit more to the class, but that isn't relevant to the question.
template<typename T>
class MyClass
{
private:
//Constructor and other bits and peices you don't need to know about
static std::set<std::string> StoredKeys;
public:
static bool GetValue(T &Value, std::string &Key)
{
//implementation
}
static SetValue(const T Value, std::string &Key)
{
//implementation
StoredKeys.Insert(Key);
}
static KeyList GetKeys()
{
return KeyList(StoredKeys);
}
};
Later on in some other part of the application I want to get all the Keys for all of the values - regardless of type.
Whilst I am fairly confident that at the moment only 3 or 4 types are being used with the class so I could write something like:
KeyList Keys = MyClass<bool>::GetKeys();
Keys += MyClass<double>::GetKeys();
Keys += MyClass<char>::GetKeys();
This will need to be updated each time a new type is used. It also has the downside of instantiating the class if it's not used anywhere.
I think (again I could be wrong) that metaprogramming is the answer here, some sort of macro maybe?
We're using boost, so I'm guessing the MPL library could be useful here?
This aspect of STL is a bit new to me, so I'm happy to read up and learn as much as I need, just as soon as I know exactly what it is I need to learn to engineer a solution.
Move StoredKeys into a non-template base class class MyClassBase, or add an AllStoredKeys static member to a non-template base class.
Alternatively, create a static init method called from SetValue that adds a pointer to StoredKeys to a static list.
There's no magic. If you need to enumerate all the types used to instantiate MyClass in your program, then you have to enumerate them explicitly, somewhere. somehow. And you have to manually update the list whenever it changes.
With template metaprogramming, the number of places you need to update manually can be reduced down to one, but you do need that one place.
Fortunately, in this particular problem you don't need to enumerate all the types. You just need to store all keys in one set, as opposed to splitting them between several sets. You may create a common non-template base to MyClass and add static std::set<std::string> StoredKeys there (or perhaps make it a multiset if there's a possibility of identical keys in different type-specific sets).
The first answere: Its not possible!
Template classes dont actually have a "generics" in common (like in java) but a separate classes which dont have anything to do with eachother.
The second answere: Theres a workaround. One can define a base class MyClassBase which defines properties shared by all templated subclasses. The problem is that you have a singleton pattern here which might makes the situation a bit more compilcated. I think a solution might look like this:
class MyClassBase {
static std::vector<MyClassBase*> childs;
static KeyList getAllKeys(){
//iterate over childs here and call ->GetKeys
}
virtual KeyList GetKeys() = 0;
template<typename T>
static T* instance() {
T* instance = MyClass<T>::instance();
if(std::find(childs.begin(), childs.end(), instance) != childs.end()){
childs.push_back(instance);
}
return instance;
}
};
Please forgive me any syntactic errors; I just typed that in the Stackoverflow editor, but i think it should make my point clear.
Edit:
I just saw that I named the singleton method of the subclasses also instance(). This will probably not work. Give it some other name like privateInstance() or so. Then you must change T* instance = MyClass<T>::instance(); to T* instance = MyClass<T>::privateInstance();

What's the best strategy for typedef'ing shared pointers?

I have a quick question regarding the use of typedefs for lengthy templates. The crux: I've found myself in something of a pickle—there doesn't seem to be a good place to place typedefs except local to client functions. While there are similar SO questions (see here for example), none seem to address this exactly. Please note that this question doesn't address whether typedefs are desirable in what follows—I've tried to simplify things for expository purposes.
My problem has arisen while working with boost::shared_ptr<T>. Basically, I want to do the following:
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<Widget> WidgetPtr;
Placing this typedef in the Widget declaration header seems ugly. There seem to be two considerations here: (i) if Widget itself doesn't make use of shared pointers in its members, we've added an additional include (as we can't forward declare the boost::shared_ptr template class—correct me if I'm wrong?) (ii) if we want to make use of this typedef during the declaration of another class (call that class Foo) we violate best practices by including Widget.h instead of simply forward declaring Widget or including WidgetFwd.h... unless this typedef is duplicated in the latter. Furthermore, it doesn't seem make sense to typedef boost::shared_ptr<Widget> during the declaration of Widget itself—we seem to be mixing Widget's declaration with an anticipation of how clients will make use of the Widget interface.
Okay, so that's bad, but this is worse: if I don't attempt some combination of the above I end up with duplicate typedefs in client code, which yields inconsistency (and hence, likely, error)—the whole point being that given Widget, a WidgetPtr typedef should act as a type in its own right. Example: we don't want Foo to make use of one WidgetPtr, a typedef of boost::shared_ptr, while Bar is using WidgetPtr as a typedef for std::auto_ptr.
Another method (and one of the few that I've seen mentioned in online discussion) would be to make the typedef a public member of Widget and then use Widget::Ptr:
class Widget {
// ...
public:
typedef boost::shared_ptr<Widget> Ptr;
};
Again, I don't like this as (i) it suggests that the pointer type is somehow a member of the class and (ii) it leads to a wonky interface. Worse still: since every class that I write can potentially be pointed to using smart pointers, I end up chasing the imaginary client's tail. Ugly, ugly, ugly.
As it stands, I've removed the typedefs from this codebase (as they led to serious confusion, duplication) and re-introduced them locally in selected functions. Here again there's a problem with inconsistent usage but it's not quite as severe.
The only other solution I can think of—and again I'm not sure whether this is considered good practice—would be to have a utilities header in which the typedefs are placed, potentially within their own namespace. In this header we'd include and be done with it.
Am I missing something obvious or is this just plain tricky?
PS—Apologies for the length of the above; I couldn't find a simpler way of fully expressing the problem.
Furthermore, it doesn't seem make sense to typedef boost::shared_ptr during the declaration of Widget itself—we seem to be mixing Widget's declaration with an anticipation of how clients will make use of the Widget interface.
First of all, this is not at all wrong - after all, the means of how the clients will (and can) use the interface is part of the interface itself; and for C++, not being garbage-collected, memory management of objects is a rather crucial part of their interface.
So there are two cases. In one case, the Widget would anticipate it would be used through a shared pointer. This would mean that eg. child widgets obtained from a widget are returned as shared_ptrs, everywidget created has it shared_ptr and so on. It would be totally legitimate to typedef WidgetPtr in the same header as Widget.
In the second case, Widgets would expect to be managed eg. by ordinary new and delete. The clients can use shared_ptrs in special cases, but nothing says eg. a printer dialogue routine can't use auto_ptr instead. The clients have to be prepared that if wptr is a shared_ptr, the line
shared_ptr<Widget> w2(wptr->firstChild()->parent());
leads to a disaster.
Your question seems to indicate the latter is your case. So IMHO, what you've done is OK. The clients can choose their means of managing Widget objects, as long as it doesn't affect other clients.
I don't like a library dictating the use of a particular smart pointer, but I tolerate it if it is necessary.
If you wish to force users to always use a shared_ptr to manipulate a widget, it's impossible, so don't even bother trying.
On the other hand, if you have a method from Widget which returns a boost::shared_ptr<Widget>, then providing a (sane) typedef might simplify the client code.
I would therefore promote the use of an inner typedef:
class Widget
{
public:
typedef boost::shared_ptr<Widget> Ptr;
Ptr AccessFirstChild();
}; // class Widget
in which case it's perfectly okay to #include the necessary headers.
You are overthinking this in my opinion. Everybody who wants to have a shared_ptr<Widget> is going to have to include the Widget header file anyway. Putting the typedef (which is a good idea imo) in Widget.h makes 100% sense to me.
My approach (using underbar types, just because it is how I do it)
class Type
{
public:
typedef shared_ptr<Type> ptr;
typedef shared_ptr<const Type> const_ptr;
};
I have found the const_ptr version is pretty darn useful.
I used to structure my C++ code into libraries. A library would have a bunch of headers for client consumption, all inside the include/LibraryName directory. Also, I would have one header called Fwd.h inside this directory with forward declarations of all classes along with their pointer typedefs.
In addition, each public header would include Fwd.h so that including the header would automatically give you all forward declarations and pointer typedefs. This worked really well in practice.
Not all classes are necessary to place in a shared_ptr though. I would only create pointer typedefs for types that I expected to be created dynamically, and in this case I would supply a factory. This has the added benefit that you may get away with supplying client code with interface types only, and hide concreted implementations in your library's src directory. Not specifically what you asked advice for, but this gives the complete picture of my method. As a final point, it's also possible to supply a convenience header called LibraryName.h that includes the Fwd.h and all other public headers.
Good luck!
I generally use this approach to ease typing and makes a generic shared pointer interface for classes.
Do note it's C++0x.
#include <iostream>
#include <memory>
template <class T>
struct SharedVirtual
{
typedef std::shared_ptr<T> VPtr;
};
template <class T>
struct Shared
{
typedef std::shared_ptr<T> Ptr;
template <class... P>
static Ptr ptr(P&&... args)
{
return std::make_shared<T>(std::forward<P>(args)...);
}
};
class Foo : public SharedVirtual<Foo>
{
public:
virtual void foo() const = 0;
};
class Test : public Foo, public Shared<Test>
{
public:
void foo() const { std::cout << "Hai u!" << std::endl; }
};
void print(const Foo::VPtr& ptr)
{
ptr->foo();
}
int main()
{
auto ptr = Test::ptr();
print(ptr);
}
Second part first: use a namespace, i.e.:
namespace WidgetStuff {
class Widget { ..
typedef shared_ptr<Widget> WidgetPtr;
..
If you want to split it up:
namespace WidgetStuff {
class Widget { ...
}
...
namespace WidgetStuff {
typedef ...
You're the library author, you own the namespace, so no one else should invade it.
And now part one is answered too, if you choose you can do:
#include <widget.h>
#include <widget_utils.h>
by splitting up the namespace as above. The effect is no one has to use the utilities, whether or not they do they should not invade your namespace, so they're free to make WidgetPtr mean something else, as long as it isn't in your namespace.