Context
I oftenly use UUID implementation of Boost library to identify derived classes.
To do so I usually use the following :
In the declaration file :
#include "ClassA.h"
#include <boost/uuid/uuid.hpp>
class SubClass1 : public ClassA {
public:
static const boost::uuids::uuid classId; // 7feb24af-fc38-44de-bc38-04defc3804de
...
};
In the implementation file :
#include "SubClass1.h"
#include <boost/uuids/uuid_generator.h>
const boost::uuids::uuid SubClass1 ::classId = boost::uuids::string_generator()("{7feb24af-fc38-44de-bc38-04defc3804de}");
...
Question
I would like to know if it is possible to assign a value to the UUID in the declaration file.
Ideas
At first, I thought it was possible because Boost implementation is POD. Therefore I tried several ways to assign a value directly in the header using aggregate initializers (see boost documentation for an example of non static aggregate initializers) :
static const boost::uuids::uuid classId = { 0x7f, 0xeb, ... };
Unfortunately, it failed at compilation (the compiler can only initialize static const integral type).
Have you any suggestions to solve this issue, preferably using the Boost implementation of UUIDs ?
The easiest way to define a non-integral constant as a class member in a header file is to wrap it in a function, like this:
typedef whatever Uuid;
class MyClass
{
public:
static Uuid const& uuid()
{
Uuid const theValue = ...;
return theValue;
}
};
If you want it as an actual constant, not a function, then you can use a little templating trick, like so:
template< class Dummy >
class MyClass_constants
{
public:
static Uuid const uuid;
};
template< class Dummy >
Uuid const MyClass_constants<Dummy>::uuid = ...;
class MyClass
: public MyClass_constants<void>
{};
With C++11 you can use constexpr, like this:
class MyClass
{
public:
static Uuid constexpr uuid = ...;
};
but, although a test of that compiles fine with no linker warnings with g++ 4.7.1, it's so new that I'm not sure if the standard's One Definition Rule actually supports it, or whether, with such definition in multiple translation units, I'm into Undefined Behavior.
So, if you want to do the constexpr, perhaps ask a separate question about the ODR.
As an alternative you can wait for the C++2040 standard and then just write
inline static Uuid const uuid = ...;
It is food for thought that, as shown, this hypothetical future feature can be emulated even in C++98, i.e. that all that's needed is already implemented by compiler and linker, and has been since the first standard. And yet, that that simple feature is lacking in the language. I believe that it's due to a kind of haphazard historical language evolution.
Anyway, I'd go for the simple function wrapper shown first. :-)
Related
I often need to define string constants associated with a class. Examples would be XML attributes, default filenames and many more.
In Java I would simply define something like
public static final String KEY = "attribute";
inside the class or interface.
In C++ the following would not compile:
class Example {
public:
static const std::string KEY = "attribute";
}
Instead, I would have to write:
class Example {
public:
static const std::string KEY;
}
const std::string Example::KEY = "attribute";
This is something I absolutely want to avoid because of its redundancy and verbosity.
The best solution I found so far is to use functions:
class Example {
public:
static std::string KEY() const { return "attribute"; }
}
This also provides some encapsulation and flexibility. However it might seem a bit weird to use a function just to define a constant.
So my question is, does this solution have major drawbacks and if yes, what are better alternatives?
In c++03, your best option is to use a function the way you are using, and this is awkward. The only thing is, why are you returning std::string and paying it's construction price, when you can return const char* const free of charge.
If, for some reason, you really have to have const std::string (again, it runs against my whole experience, so you might want to reconsider) following code works best in terms of efficiency (your current version calls std::string constructor on every call!):
class Example {
public:
static const std::string& key() {
static const std::string the_key = "That's my key!";
return the_key;
}
}
In c++11, you have several options, of which I find the best a constexpr:
class Example {
public:
static constexpr const char* const KEY = "TheKey";
}
The other option is in-place initialization of your const string, but why pay the price of it?
class Example {
public:
static const std::string KEY = "TheKey";
};
Whereas with Java, classes and their static members are loaded along with the class—which means that the class as a unit, or as part of a JAR, is replaceable—in C++ it doesn't go that way. If you stick things in headers, you pay the price of not being able to replace them until you re-compile everything that included them.
That's why the idiomatic—and most beneficial—way would be to indeed declare them in the header and provide the implementation where it belongs, in the translation units, which can be linked in to whatever other binaries. So consider readjusting your outlook (I moved from C# to C++ so I had this happen to me more than once).
But you don't have to go the way of strings at all. You can create enums, which is a much more elegant and type safe way to achieve this sometimes. With enums (and specifically enum classes), you can't just pass in the wrong string. You have to pass in one of a set of valid values.
As an example you could do:
class Example {
public:
enum class Attributes {
One,
Two,
// ...
};
}
And then, when it matters, and when you have local knowledge of what's what, you can map the enum values to actual strings or whatnot that the actual implementation requires.
You can define constructor of the class so that each time the class is used the constructor will automatically assign the value "attribute to the string"
class Example {
public:
static const std::string KEY;
Example()
{
KEY="Attribute";
}
};
My question is similar to: Can't use macro define class in C++, but is a little more complicated:
class ABC
{
public:
DECLARATION(ABC)
private:
void ABCFun1();
void ABCFun2();
// ... and so on
}
#define DECLARATION(TYPE)\
std::string GetClassName()\
{\
return std::string(#TYPE);
}\
// the macro can goes on to declare more
// common interfaces, like Initialize(), ...etc.
So, the point is, I can use this macro to generate other classes like DEF, GHI...etc,
where all of them shares the common part of DECLARATION, but also having their own private
parts.
If there isn't the need of GetClassName(), which seems can only be implemented using macro #,
then I can use inheritance to put them together.
Or, if there aren't the private things, I can use template.
So, with these 2 things mixed up, is there any way to avoid the macro?
Thanks!
You can us the CTRP to generate some functions. But remember that names won't be available unless you use macros (that will change when compile-time reflection will be made into the standard, maybe for C++17).
CRTP:
template<typename T>
class Base
{
public:
void myFunc()
{
((T*)this)->functionA();
((T*)this)->functionB();
// ...
}
};
class ABC : public Base<ABC>
{
// ...
};
Edit: BЈовић answer is right, but some comments about RTTI:
it is not portable
typeid(T).name() is implementation dependant (it can return "" for every type if an implementor wanted to)
it is slow.
See this question about RTTI and LLVM, for example (or this one about performance).
To store strings, you should use the preprocessor as for now. Note that it does not work with templated parameters (ie, if you have template<typename T>, then #T will expand to "T", not the actual typename).
Then, there is a technique that allows to pass a string to a template parameter (sort-of):
#define NAME( _n_ , _t_ ) \
struct _t_ \
{ \
static const char* asName() \
{ \
return #_n_; \
} \
}
It changes the string to a type. The string in itself is a litteral, so it is put straight into the executable (and is read-only, attempts to modify it will most likely result in a crash).
I use this in the SPARK Particle Engine, for example, where I implemented a reflection module.
As far as I can see from the vague "the macro goes on..." comment, the DECLARATION macro seems to do one or several of these things:
define members are independent of ABC
define members (methods or data members) that depend on the type ABC
define members that use the string "ABC"
tl;dr: #1 is trivial, as you noted in the question. #2 is relatively easy, use CRTP, #3 is not satisfactorily doable without a macro.
update:
In the comments below you mention that you want a guarantee that the string and the class name be "sync-ed". This is definitely impossible without macros in current C++. (see "update" below)
The first is easy to achieve without a macro - just inherit from a ordinary base class that defines the members.
The second can be done relatively easy too, via a CRTP: create a template class that takes the type as parameter and inherit from the template, instantiated with the type itself:
template <class T>
class Base {
public:
void doSomething(T const&);
};
class ABC : public Base<ABC> {
// inherited void doSomething(ABC const&);
};
The third one is tricky and not easily solvable without at least a bit of boilerplate.
C++ has no features apart from macros that convert a name (class name, function name, variable name...) into a string representing that name. (such language features are part of a family of features commonly called reflection). An exception is typeid(T).name(), nut the outcome is not standardized, so it may or may not give you the name of the class, something different, readable or unreadable or just an empty string.
So, to (portably and realiably) get a string "ABC" for a class ABC you have to write "ABC" at least once in addition to the class definition. That's not so bad yet, you have to do something similar for #2 as well, as it seems impossible to use the type of ABC without explicitly mentioning ABC again.
Update: Since you have to explicitly type both the string and the class name, there can be no guarantee that both are always the same, except with a macro. Even the macro you have in the question is prone to changes/typos:
class ABC {
DECLARATION(ACB);
};
This will give a wrong class name if the macro only provides the stringified version of it's argument without doing something with the type (in that case the compiler would tell you that ACB is no type). If you want the guarantee, use one macro that does everything, including the class definition:
#define CLASS_DEF(x) \
class x##_base { \
std::string GetClassName() { \
return std::string(#x); \
} \
}; \
class x : public x##_base
and then later:
CLASS_DEF(ABC)
{
private:
void ABCFun1();
void ABCFun2();
// ... and so on
}
Putting it in a base class makes it possible to write the macro and then just a normal class body.
So what can we do for #3 without a macro, if we don't need the sync-guarantee?
providing the string as a template parameter to some base class would be the nicest way but is, in short, not possible. This article covers strings as template parameters and has to fall back to macros in the end. The closest we can get is some form of the boost::mpl::string<'Hell','o Wo','rld!'> mentioned in the article. The length would be limited by some arbitrary definition, if C++11 variadic templates are not available, and the definition of the base class (or boost::mpl::string) would probably use a good deal of macro magic itself, but at least you are rid of self-defined macros in the class itself. Something that uses #2 and #3 would have to look somewhat like (i make the name longer to demonstate the restrictions of the approach)
class ABCDE: public Base<ABCDE, 'ABCD', 'E'> { /* ... */ }
having the string as a static data member constant with a predefined name. This is an option that fits well together with CRTP, if you have to use it anyways:
template <class T>
class Base {
public:
std::string GetClassName() const {
return T::name;
};
};
class ABC : public Base<ABC> {
public:
constexpr static char const * name = "ABC";
};
In C++03, you would have to use a static const member that has to be defined outside the class definition (i.e. in ABC.cpp)
having the string as a nonstatic data member of ABC works similarly:
template <class T>
class Base {
public:
std::string GetClassName() const {
return static_cast<T const*>(this)->name;
};
};
class ABC : public Base<ABC> {
public:
const std::string name = "ABC";
};
This requires C++11 for the in-class member initialization. In C++03 the name has to be properly initialized in every constructor.
having the string as data member of the base class works and should be preferred imo, if you don't have type-dependent members, i.e. if you don't need CRTP to do #2:
class Base {
public:
Base(std::string nm) : name(nm) {}
std::string GetClassName() const {
return name;
};
std::string name;
};
class ABC : public Base {
public:
ABC() : Base("ABC") {}
ABC(int i) : ABC() { /*another ctor*/ }
};
To do the initialization of Base with the class name just once you can use the C++11 delegating constructors, although it's not much different writing Base("ABC") or ABC() in each initializer list.
If you just need to get the type's name, you can use typeinfo::name() method.
You could use CRTP, which contains everything that you need. Something like this :
template< typename T >
class MyBase
{
public:
MyBase() : className( typeid(T).name() ){}
virtual ~MyBase(){}
std::string className;
// common interfaces, like Initialize()
};
then use it :
class A : public MyBase<A>
{
};
I want to store some additional information about classname during inheritance:
#define CLASS_TO_STRING(name) #name
class IBase {};
template <typename T>
struct BaseManager
{
static const char* MANAGER_TAG = CLASS_TO_STRING(T);
};
std::map<const char*, IBase*> mManagers;
template <typename T>
void addManager(BaseManager<T>* manager)
{
mManagers[T::MANAGER_TAG] = manager;
}
So, when I call addManager with some object of type inherited from BaseManager I get an error that BaseManager<TYPENAME>::MANAGER_TAG is undefined. I understand the reason of the problem but can't understand how to resolve it.
Apart from marcin_j's comment about in-class initialization (which works only in C++11 and for nonintegral types it requires constexpr), the real problem is this:
static const char* MANAGER_TAG = CLASS_TO_STRING(T);
When this line gets parsed by the preprocessor, CLASS_TO_STRING will turn T into the string literal "T". What's really going on here is that the preprocessor (the one performing macro substitution) has absolutely no idea of the template system and that T is a template parameter. You need a different approach here.
You can change const char* to constexpr but I am afraid all you will get from CLASS_TO_STRING(T) is T (at least g++ gives me T on output - and thats because preprocessor runs before compilation and template instantiation).
also instead of T::MANAGER_TAG, you should BaseManager<T>::MANAGER_TAG. And your BaseManager should inherit from IBase if :
mManagers[BaseManager<T>::MANAGER_TAG] = manager;
is supposed to work.
The reason you get your error is I suppose that in-class initialization of static data member, works only for const integral types.
Say I have the following example:
#include <cstdlib>
class A {
public:
static const std::size_t value = 42;
};
In short, I have (or better, want) a class A with a static const std::size_t member called value with the value 42 (determined at compile time).
Now, IIRC, this only works fine under certain circumstances. It doesn't, for example, when you take the address of A::value. In order for this to work fine in all cases you'd need to add a definition in some implementation file:
const std::size_t A::value;
However, I can't do this, because I want this file to be header-only. Another common solution is this:
class A {
public:
enum { value = 42 };
};
I don't like this solution either, because I'd like the type of A::value to be std::size_t.
What is a good solution to this problem? Preferably a small and portable solution, not something with huge macro magic like BOOST_STATIC_CONSTANT.
I'd like a solution for C++03, not C++11 (it's trivial there).
First of all, using the unsigned size_t type for numbers, you're likely to run into implicit promotion problems. So, good idea to use its corresponding signed type, which is called ptrdiff_t. Which, as it happens, is the result type of a pointer difference expression.
Also, due to changes in C++11, it’s generally a good idea to include <stddef.h> and not <cstddef>, i.e., write ::ptrdiff_t or just plain ptrdiff_t, not std::ptrdiff_t.
Now, here's how to do the header file extern linkage constant thing:
template< class Dummy >
struct A_constants_
{
static ::ptrdiff_t const value;
};
template< class Dummy >
::ptrdiff_t const A_constants_<Dummy>::value = 42;
typedef A_constants_<void> A_constants;
class A
: public A_constants
{
public:
// Whatever
};
Then you can use it like this:
foo( A::value );
There are also some other ways of doing this, but the above is about the simplest and easiest to get right.
I am trying to write an application that is loading its extensions dynamically during runtime. I used Boost Preprocessor library to write a preprocessor function that, given a list of names, declares a class for each name (and make all of them subclasses of some AbstractPlugin class) and then declares a Boost MPL sequence containing that classes. Then I wrote a class that tries a pointer to AbstractPlugin if it could be cast to any of the types in that MPL sequence.
The problem here is that my preprocessor function needs a full list of all extensions I want to create and load. Is there some technique that lets me register each extension in a separate file?
Update:
I believe, my explanation of situation was too vague, so I decided to make it more specific.
I would like to define a collection of extension types. For each extension type there could be any number of extensions. During runtime the program loads external library, resolve the entry point function, call it and, as a result, get a pointer. Then it tries to cast that pointer to all registered extension types (using dynamic_cast, so classes for extension types all inherit from some polymorphic base class). If a cast to some extension type succeeds, the casted pointer is used in a call to special handler for that extension type.
The number of extension types is known at compile time (while, obviously, the number of extensions is infinite). Using my aproach the loader class uses this knowledge to check whether there exists a handler for each extension type (if not, the program doesn't compile). Also, my aproach doesn't force classes for extension types know anything about the loader (so it is easy to modify the loader). But it would be more convenient if each extension type registered itself.
You can make all your classes self-registering in some sort of collection. Here's a skeleton approach:
Base.hpp:
#include <memory>
#include <unordered_map>
#include <string>
struct Base
{
virtual ~Base() = default;
using create_f = std::unique_ptr<Base>();
static void registrate(std::string const & name, create_f * fp)
{
registry()[name] = fp;
}
static std::unique_ptr<Base> instantiate(std::string const & name)
{
auto it = registry().find(name);
return it == registry().end() ? nullptr : (it->second)();
}
template <typename D>
struct Registrar
{
explicit Registrar(std::string const & name)
{
Base::registrate(name, &D::create);
}
// make non-copyable, etc.
};
private:
static std::unordered_map<std::string, create_f *> & registry();
};
Base.cpp:
#include "Base.hpp"
std::unordered_map<std::string, Base::create_f *> & Base::registry()
{
static std::unordered_map<std::string, Base::create_f *> impl;
return impl;
}
Now to use this in a client:
Derived.hpp:
#include "Base.hpp"
struct Derived : Base
{
static std::unique_ptr<Base> create() { return std::make_unique<Derived>(); }
// ...
};
Derived.cpp:
#include "Derived.hpp"
namespace
{
Base::Registrar<Derived> registrar("MyClass");
}
The constructor of the Base::Registrar<Derived> takes care of registering the class Derived under the name "MyClass". You can create instances of Derived dynamically via:
std::unique_ptr<Base> p = Base::instantiate("MyClass");
The code could/should be improved by detecting repeat registrations, printing a list of available classes, etc. Note how we avoid any static initialization ordering problems my making the actual registry map object a block-static object, which is guaranteed to be initialized before its first use, and thus destroyed only after its last use.
It is not difficult to implement such an extension framework using the abstract factory pattern.
http://en.wikipedia.org/wiki/Abstract_factory_pattern
You can register those abstract factory functions/objects in a global list, and do whatever you want to do base on it.
As it turns out what I want is impossible. The reason for that is "register" in this context means "put a type inside type sequence" and type sequences are immutable because they are types themselves. So one should either create this type sequence manually, or as some people suggested move the "registration" into runtime.