Enforce type safety in C++ without using extra classes - c++

I am somewhat familiar with type safety, and have used it successfully before in methods which receive several parameters of the same type (bool) to avoid confusion. For example:
// Old version of the method
void sendPackage(bool sendImmediately, bool dividePacket);
// Type safe version
enum SendImmediatelyPreference
{
SEND_IMMEDIATELY,
DO_NOT_SEND_IMMEDIATELY
};
enum PacketDivisionPreference
{
DIVIDE_PACKET,
DO_NOT_DIVIDE_PACKET
};
void sendPackage(
SendImmediateltPreference immediatePref,
PacketDivisionPreference divisionPref);
So the cryptic sendPackage(true, false) becomes sendPackage(SEND_IMMEDIATELY, DO_NOT_DIVIDE_PACKET).
The problem is that this is only an option for bool. I have a method that accepts several std::vector<std::string> and I'd like to minimise the posibility of the user inputting the arguments in the wrong order.
I can think of creating different classes which contains an std::vector<std::string> and either override tons of the std::vector methods or expose the internal vector.
Is there an easier way, some sort of typedef which enforces type safety? Using boost would be okay.

How about an alternative approach using named parameters? There are several ways of going about this in C++ described here. The tag approach using a tuple looks reasonable. There is also boost parameter.
This doesn't offer strong type safety, but you could argue that the user is just as likely to call the wrong constructor to make their type safe object as they are to use the wrong tag when calling your function. This situation is less likely to occur if the types are used throughout your application vs defined only for one particular function.
See also the discussion of boost strong typedef vs parameter for a similar purpose here.

Not sure I understood you correctly, but maybe this can help:
enum SendImmediatelyPreference : bool // allows only 2 options:
{
DO_NOT_SEND_IMMEDIATELY, // false
SEND_IMMEDIATELY // true
}

What about creating a class that inherits (public) from std::vector to have a strong typecheck. The advantage is that you only need to rewrite constructors..
You can also regroup your parameters in a std::unordered_map>, to implement argument as a dict (like in python, or javascript)

BOOST_STRONG_TYPEDEF is precisely a typedef which enforces type safety.
However, this answer provides some caveats related to using this strong typedef for just a function, and argues that the types should be used all over the code to prevent unnecessary castings.

I like to bundle the parameters in a config class or struct. For example:
struct SendOptions
{
bool send_immediately = false;
bool divide_packet = false;
// ...
};
void sendPackage(SendOptions options);
This has the additional advantage the extra options can be added later without needing to change the interface of sendPackage(SendOptions).
This does not increase type safety but it does help to prevent errors (especially if there are a lot of parameters), which is probably the goal you're trying to achieve.

Related

Using std::hash<uint64_t> for custom class

Do the following two return statements return the same thing?
class NonTrivialClass
{
public:
size_t hash() const
{
// variation 1
return std::hash<uint64_t>::_Do_hash(my_val_);
// variation 2, wanted to avoid creating the named object
std::hash<uint64_t> hasher;
return hasher(my_val_);
}
private:
// relevant info for hashing purposes is stored here
uint64_t my_val_;
}
I intuitively wanted to write something like
return std::hash<uint_64>(my_val_);
which did not compile (because I didn't init an instance of the struct?!). Is there a another way I am missing? Is worrying about creating the named hasher struct unneccessary?
A simpler way of writing it is using a temporary object:
return std::hash<uint64_t>{}(my_val_);
It does the same thing as your second approach.
I can't tell for sure what _Do_hash does, but in any case it is non-standard and should not be used, to avoid portability issues.
Since a google search didn't turn up any documentation of the function, I would assume that it is an implementation detail of the standard library implementation that you are using and that isn't meant to be used by user code. Therefore you shouldn't use it at all, even if you don't care about portability.
Also note that it doesn't matter for performance whether you use your approach with a named variable or my approach using a temporary. The compiler will almost surely generate identical code from it. Which you use is purely a matter of code style.

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.

Boost Parameters library

Recently I found Parameters library in the Boost. Honestly I didn't understand the reason why this is a part of Boost. When there is need to pass several parameters to the function you can make a structure from them, like:
struct Parameters
{
Parameters() : strParam("DEFAULT"), intParam(0) {}
string strParam;
int intParam;
};
void foo(const Parameters & params)
{
}
Parameters params;
params.intParam = 42;
foo(params);
This is very easy to write and understand.
Now example with using Boost Parameters:
BOOST_PARAMETER_NAME(param1)
BOOST_PARAMETER_NAME(param2)
BOOST_PARAMETER_FUNCTION(
(void), // 1. parenthesized return type
someCompexFunction, // 2. name of the function template
tag, // 3. namespace of tag types
(optional // optional parameters, with defaults
(param1, *, 42)
(param2, *, std::string("default")) )
)
{
std::cout << param1 << param2;
}
someCompexFunction(param1_=42);
I think it's really complex, and the benefit is not that significant..
But now I see that some of the Boost libraries (Asio) use this technique.
Is it considered a best practice to use this library to pass many arguments?
Or maybe there are real benefits of using this library that I don't see?
Would you recommend using this library in the project?
Your technique requires creating a lot of temporaries (given enough
parameters) and will be rather verbose in some cases. Something that
is even more tricky is documentation. If you go down the route of
configuration structs, you will have two places where you need to
explain your parameters. Documenting Boost.Parameter functions is easy
in comparison.
It also keeps the verbosity down and allows me to reuse arguments for
whole families of functions instead of composing a new configuration
carrier over and over again.
If you don't like the library, don't use it. It has several other
drawbacks you haven't mentioned (heavy includes, high compile times).
Also, why not just provide the best of two worlds? One function using Boost.Parameters and another using configuration structs, where both dispatch on a common implementation. Manage headers correctly and the "don't pay for what you don't use" promise will be kept. The price is maintainability. But you can always deprecate one interface if your users don't like it.
Well, I don't use this library, but the key is that you can pass parameters by name.
Imagine that you have a function with a lot of parameters, and in most cases you only want to use a few. Maybe not always the same few, so putting these in front of the list (so the others can be supplied as defaults) won't help. That's where the "named parameter" stuff comes in: you just give the names and values of the parameters you want to pass, in any order you like, and the others will be defaulted. You don't even have to know all the possible parameters; a later version of the function can add new parameters without breaking anything (provided the defaults for the new parameters are chosen to mimic the old behavior).
In comparison to structures, you could make a structure and initialize everything with defaults. That's pretty much how this kind of stuff works internally anway, if I'm not mistaken, by passing a parameter object around and setting values there before passing it into the actual function at the end.

Alternatives to passing a flag into a method?

Sometimes when fixing a defect in an existing code base I might (often out of laziness) decide to change a method from:
void
MyClass::foo(uint32_t aBar)
{
// Do something with aBar...
}
to:
void
MyClass::foo(uint32_t aBar, bool aSomeCondition)
{
if (aSomeCondition)
{
// Do something with aBar...
}
}
During a code review a colleague mentioned that a better approach would be to sub-class MyClass to provide this specialized functionality.
However, I would argue that as long as aSomeCondition doesn't violate the purpose or cohesion of MyClass it is an acceptable pattern to use. Only if the code became infiltrated with flags and if statements would inheritance be a better option, otherwise we would be potentially be entering architecture astronaut territory.
What's the tipping point here?
Note: I just saw this related answer which suggests that an enum may be a better
choice than a bool, but I think my question still applies in this case.
There is not only one solution for this kind of problem.
Boolean has a very low semantic. If you want to add in the future a new condition you will have to add a new parameter...
After four years of maintenance your method may have half a dozen of parameters, if these parameters are all boolean it is very nice trap for maintainers.
Enum is a good choice if cases are exclusive.
Enums can be easily migrated to a bit-mask or a context object.
Bit mask : C++ includes C language, you can use some plain old practices. Sometime a bit mask on an unsigned int is a good choice (but you loose type checking) and you can pass by mistake an incorrect mask. It is a convenient way to move smoothly from a boolean or an enum argument to this kind of pattern.
Bit mask can be migrated with some effort to a context-object. You may have to implement some kind of bitwise arithmetics such as operator | and operator & if you have to keep a buildtime compatibility.
Inheritence is sometime a good choice if the split of behavior is big and this behavior IS RELATED to the lifecycle of the instance. Note that you also have to use polymorphism and this is may slow down the method if this method is heavily used.
And finally inheritence induce change in all your factory code... And what will you do if you have several methods to change in an exclusive fashion ? You will clutter your code of specific classes...
In fact, I think that this generally not a very good idea.
Method split : Another solution is sometime to split the method in several private and provide two or more public methods.
Context object : C++ and C lack of named parameter can be bypassed by adding a context parameter. I use this pattern very often, especially when I have to pass many data across level of a complex framework.
class Context{
public:
// usually not a good idea to add public data member but to my opinion this is an exception
bool setup:1;
bool foo:1;
bool bar:1;
...
Context() : setup(0), foo(0), bar(0) ... {}
};
...
Context ctx;
ctx.setup = true; ...
MyObj.foo(ctx);
Note:
That this is also useful to minimize access (or use) of static data or query to singleton object, TLS ...
Context object can contain a lot more of caching data related to an algorithm.
...
I let your imagination run free...
Anti patterns
I add here several anti pattern (to prevent some change of signature):
*NEVER DO THIS *
*NEVER DO THIS * use a static int/bool for argument passing (some people that do that, and this is a nightmare to remove this kind of stuff). Break at least multithreading...
*NEVER DO THIS * add a data member to pass parameter to method.
Unfortunately, I don't think there is a clear answer to the problem (and it's one I encounter quite frequently in my own code). With the boolean:
foo( x, true );
the call is hard to understand .
With an enum:
foo( x, UseHigherAccuracy );
it is easy to understand but you tend to end up with code like this:
foo( x, something == someval ? UseHigherAccuracy : UseLowerAccuracy );
which is hardly an improvement. And with multiple functions:
if ( something == someval ) {
AccurateFoo( x );
}
else {
InaccurateFoo( x );
}
you end up with a lot more code. But I guess this is the easiest to read, and what I'd tend to use, but I still don't completely like it :-(
One thing I definitely would NOT do however, is subclass. Inheritance should be the last tool you ever reach for.
The primary question is if the flag affects the behaviour of the class, or of that one function. Function-local changes should be parameters, not subclasses. Run-time inheritance should be one of the last tools reached for.
The general guideline I use is: if aSomeCondition changes the nature of the function in a major way, then I consider subclassing.
Subclassing is a relatively large effort compared to adding a flag that has only a minor effect.
Some examples:
if it's a flag that changes the direction in which a sorted collection is returned to the caller, that's a minor change in nature (flag).
if it's a one-shot flag (something that affects the current call rather than a persistent change to the object), it should probably not be a subclass (since going down that track is likely to lead to a massive number of classes).
if it's a enumeration that changes the underlying data structure of your class from array to linked list or balanced tree, that's a complex change (subclass).
Of course, that last one may be better handled by totally hiding the underlying data structure but I'm assuming here that you want to be able to select one of many, for reasons such as performance.
IMHO, aSomeCondition flag changes or depends on the state of current instance, therefore, under certain conditions this class should change its state and handle mentioned operation differently. In this case, I can suggest the usage of State Pattern. Hope it helps.
I would just change code:
void MyClass::foo(uint32_t aBar, bool aSomeCondition)
{
if (aSomeCondition)
{
// Do something with aBar...
}
}
to:
void MyClass::foo(uint32_t aBar)
{
if (this->aSomeCondition)
{
// Do something with aBar...
}
}
I always omit bool as function parameter and prefer to put into struct, even if I would have to call
myClass->enableCondition();

How to typeof in C++

How to simulate C# typeof-command behavior in C++?
C# example:
public static PluginNodeList GetPlugins (Type type)
{
...
}
Call:
PluginManager.GetPlugins (typeof(IPlugin))
How to implement this using C++? Maybe QT or Boost libraries provide a solution?
What about the case if you want to implement .GetPlugins(...) in a way that it loads those kinds of objects from a file (.so or .dll)?
You could use a dynamic_cast to test types as shown below:
IPlugin* iPluginPtr = NULL;
iPluginPtr = dynamic_cast<IPlugin*>(somePluginPtr);
if (iPluginPtr) {
// Cast succeeded
} else {
// Cast failed
}
This behaviour is called RTTI (Run time type information). This technique is best to be avoided, but can be beneficial in some situations.
There are two big ways to solve this. The first way is to write an interface with a pure virtual function that returns a class specific integer reference code. This code can then be used to represent a specific type. These integers could be stored in a specific enumeration.
In derived classes you can then override the method and return that class specific type.
During runtime, you can then call Plugin->getType() for instance, and it'll return its specific type. You can then perform a static_cast on the pointer to get the correct pointer of the derived type back.
The second way is to either use typeid to get the classtype of the object; but this is compiler dependant. You can also try casting your pointer using dynamic_cast; dynamic_cast returns a null pointer when it's being cast into the wrong type; and a valid one when being cast in a correct type. The dynamic cast method has a bigger overhead tho than the getType method described above.
If you want complete typeof-like behaviour, you would have to use RTTI (run-time type information). On many compilers you have to explicitly activate usage of RTTI, as it incurs run-time overhead.
Then you can use typeid or dynamic_cast to find an object's type.
If you don't want to use typeid, you'd have to use inheritance, pointers and/or overloads. Boost might help you, but it's not too hard.
Example 1:
class Iplugin { ... }
class Plugin1 : public Iplugin { ... }
class Plugin2 : public Iplugin { ... }
void getplugins(Iplugin* p) {
// ... you don't know the type, but you know
// what operations it supports via Iplugin
}
void getplugins(Plugin1& p) {
// expliticly handle Plugin1 objects
}
As you can see there are several ways of avoiding usage of RTTI and typeid.
Designing around this problem would be the best choice. Good use of object orientation can usually help but you can always create your own system for querying the type of an object by using a base class which stores an identifier for each object, for instance.
Always try to avoid using dynamic_cast as it most often uses string comparison to find the type of an object and that makes it really slow.
You can use typeof() in GCC. With other compilers, it's either not supported or you have to do crazy template mangling or use "bug-features" that are very compiler specific (like the way Boost does it).
Boost does have a typeof. C++ 0x doesn't call it typeof, but has both 'auto' and 'decltype' that provide the same kinds of functionality.
That said, I'm pretty sure none of those provides what you're really looking for in this case -- at most, they provide only a small piece of what you need/want overall.
Surely you would just use overloading?
static PluginManager::GetPlugins(Type1 &x) {
// Do something
}
static PluginManager::GetPlugins(Type2 &x) {
// Do something else
}
and then call:
PluginManager::GetPlugins(IPlugin);
Not directly answering the "how to get typeof() in C++", but I infer from your question that you are looking at how to do plugins in C++. If that's the case, you may be interested in the (not-yet)Boost.Extension library, and maybe in its reflection part.