I want to write convinient Color management class, that would allow me to use different orders of components and basically different setups. I want it to be distinguishable at compile-time.
Lets say I have this code:
template <typename _valueType>
struct RGBAColorData {
using ValueType = _valueType;
union {
struct { ValueType r, g, b, a; };
ValueType components[4];
};
};
This (even if anonymous structs are non-standard) works fine, when I want to use it like this:
RGBAColorData color;
color.r = whatever;
However, this is not the final form of my code. I want it to have "owning" class template, that would in compile-time select between XYZColorData. Lets say it looks like this:
template <typename _valueType, template <typename> _dataScheme>
struct Color
{
using ValueType = _valueType;
using DataScheme = _dataScheme<ValueType>;
// what now?
// DataScheme data; // ???
};
This makes a problem, because I want my code to be used like this:
using RGBAColorF = Color<float, RGBAColorData>;
RGBAColorF brushColor;
brushColor.r = whatever;
This would make a really convinient way to use colors, however I can't think of any solution to this problem.
Finally, maybe I have wrong approach to this and maybe this can be done with less effort, however I can't think about any other method that wouldn't involve massive amount of template class specializations.
Don't do it !
Tricking around for obtaining some nice syntactic effects is full of danger and might obliterate future evolution.
First of all, in C++ only one union member can be active at any moment. so switching the use of the array and of the struct is not guaranteed to work, even if on many compilers this may lead to the expected results.
Then, there is no guarantee for structure members to be contiguous, so that if mixing use of array and struct would work, it might still not lead to a correct result, even if on many compilers this will work as expected.
Or do it with a safer approach...
If you still like to mix the use of specific color components r, g, b and of the array, you should consider a safer approach:
template <typename _valueType>
struct RGBAColorData {
using ValueType = _valueType;
ValueType components[4];
ValueType &r=components[0], &g=components[1],
&b=components[2], &a=components[3]; // ATTENTION (see explanations)
};
ATTENTION: I made it quick and dirty. You should better implement the rule of three, with a proper constructor, a copy constructor and an assignment operator, to make sure that the references are not messed up.
I do not like this solution so much, but it works safely (online demo): the trick is to make r, g, b, a references to specific array items. You are then sure that you can mix the access way, and you are absolutely sure that the mapping between the two is correct.
But prefer clean encapsulation
The problem with your initial approach and my workaround is that they oth break the encapsulation: you have to know the inner structure of your color in order to use it.
With this approach, you'll never able to evolve. For example switching to a CMYK color scheme, or adopting a bit fields encoding would be compromised.
The proper way would be to have a set of getters and setters to completely hide the inner structure to the outside world. Of course, syntactically it does not look so nice, but then you'd really be able to write truly generic color code, where the encoding scheme could be a compile-time strategy.
Finally, I decided to use inheritance (as Ben Voigt said).
I fixed the other problem, with unions that made code unsafe, using the brilliant method proposed by this answer:
https://stackoverflow.com/a/494760/4386320
Related
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.
I am not very familiar with C++ , and while I am trying some test programms I came to a question regarding the best if I may say so way to define some primitive elements in C++ code.
Let's take a class that describes rectangles. It would create them, draw them , rotate, resize, etc... now in most cases we have to deal with points on the canvas.
The rectangle its self is described by 2 points: Upper Left and Lower Right corner.
Also in order to Rotate it, you need an angle, and a point(anchor point).
Or maybe to move it you need a new anchor point for the given rectangle. I guess I made my point in using points .
So what is more efficient ? to define this primitive point as a class or as a struct?
class cPoint
{
public:
int X;
int Y;
};
or
typedef struct
{
int X;
int Y;
}sPoint;
Niether are more efficient. On a technical level, there is no difference between a class and a struct aside from default visibility of members (public in struct, private in class) and default inheritance model (public in struct, private in class).
They typedef struct {} name model is not idiomatic in C++. In fact, it's an abomination -- a holdover from C. Don't use this model. Use this struct name {}; instead. Using the typedef struct {} name; model doesn't gain you anything in C++ (it was needed in C), and may cost you sojmething in terms of maintainability. For instance, it might be harder to grep for typedef struct declarations. But since it doesn't gain you anything by doing this, there's no compelling reason not to simply do struct name {}; in C++.
Aside from technical issues, the differences between struct and class are semantic ones. It is traditional and expected that objects declared as structs are simple objects which consist of only public: data members (so-called PODs). If it has private or protected data, is expected to be derived from, or has any methods, it is declared as a class.
This guideline is open to interpretation, and is just that -- a guideline. There is nothing to prevent you from declaring an abstract base class as a struct, for example. However you may want to consider following this guideline in order to follow the Principle of Least Surprise, making your code easier to understand and maintain.
Both are nearly equivalent. More precisely, struct { is the same as class {public:
An optimizing compiler would probably generate exactly the same code. Use MELT or simply pass -fdump-tree-all (beware, that option produces hundreds of dump files) to g++ (assuming you use a recent GCC compiler) -preferably with some optimization like -O - to find out (or look at the produced assembler code with g++ -O -fverbose-asm -S ...)
typedef struct is actually the C way to do this. In C++ the two versions would look very similar: Your class as written, and the struct as follows:
struct sPoint
{
int X;
int Y;
};
The two forms are functionally identical but you can provide your future maintainers with significant information by picking and sticking to some convention about how they're used. For example one approach is that if you intend to make the data elements private and give it useful methods (for example if you use inline accessors you can insert print calls every time the methods are used) then by all means make it a class. If you intend to have the data be public and access them as members then make it a struct.
There's no performance difference between a class and a struct
A class defaults to private access, whilst a struct defaults to public access. If interoperability with C is an issue for you then you'll have to use struct, and obviously it can't have any member functions.
As an aside, there's no std::is_struct in the standard library. Instead the std::is_class method returns true if the type is a class or a structure.
Simply put, the first way is more C++, and the second way is more C. Both work, while the first way is more 'standard' now.
A struct in C++ is like a class that would have public members by default*
There is no other formal difference, though your code would probably look confusing if you started using structs as classes, especially the inheritance mechanisms where data privacy is a major benefit.
If you are about to declare private/protected members, there is really little point in using a struct, though your code will still be 100% legal.
*including inherited members, since the zealots and nitpickers around seem to think the point is of a capital importance and only ignorant heatens would fail to mention it.
Except for the fact that this fine doctrine point is defined (or rather hinted, since the inference that base classes are simply defining inherited members is left to the sagacity of the reader) in another verse of the Stoustrup Holy Bible, there is really nothing to fuss about IMHO.
To properly declare the struct in your example, use
struct sPoint {
int X;
int Y;
};
In general, structs and classes in C++ are identical, except that data is public in a struct by default. The other difference is that the struct keyword cannot be used as the type in a template, although a struct can be used as the parameter.
There is a more thorough discussion here: C++ - struct vs. class
technically, struct{} and class{} are the same.
they differ on semantic level, with different member visibility.
struct{...} is equivalent to class{public:...}
And, it is also legal to declare a class using struct keyword. (add member functions, access specifier to struct{})
Generally, using struct for Plain-Old-Data (POD) type, class for Object-Oriented type to improve readability.
typedef struct{} should only be used to hide implementation detail(eg: supply a close-source library to users)
From my opinion, in your case, using struct is better, because Point's member need to be modified directly by other code.
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.
I want to have named fields rather than indexed fields, but for some usage I have to iterate on the fields. Dumb simplified example:
struct named_states {float speed; float position;};
#define NSTATES (sizeof(struct named_states)/sizeof(float))
union named_or_indexed_states {
struct named_states named;
float indexed[NSTATES];
}
...
union named_or_indexed_states states,derivatives;
states.named.speed = 0;
states.named.position = 0;
...
derivatives.named.speed = acceleration;
derivatives.named.position= states.named.speed;
...
/* This code is in a generic library (consider nstates=NSTATES) */
for(i=0;i<nstates;i++)
states.indexed[i] += time_step*derivatives.indexed[i];
This avoid a copy from named struct to indexed array and vice-versa, and replace it with a generic solution and is thus easier to maintain (I have very few places to change when I augment the state vector).It also work well with various compiler I tested (several versions of gcc/g++ and MSVC).
But theorically, as I understand it, it does not strictly adhere to proper union usage since I wrote named field then read indexed field, and I'm not sure at all we can say that they share same struct fields...
Can you confirm that's it's theorically bad (non portable)?
Should I better use a cast, a memcpy() or something else?
Apart theory, from pragmatic POV is there any REAL portability issue (some incompatible compiler, exotic struct alignment, planned evolutions...)?
EDIT: your answers deserve a bit more clarification about my intentions that were:
to let programmer focus on domain specific equations and release them from maintenance of conversion functions (I don't know how to write a generic one, apart cast or memcpy tricks which do not seem more robust)
to add a bit more coding security by using struct (fully controlled by compiler) vs arrays (decalaration and access subject to more programmer mistakes)
to avoid polluting namespace too much with enum or #define
I need to know
how portable/dangerous is my steering off the standard (maybe some compiler with aggressive inlining will use full register solution and avoid any memory exchange ruining the trick),
and if I missed a standard solution that address above concerns in part or whole.
There's no requirement that the two fields in named_states line up the same way as the array elements. There's a good chance that they do, but you've got a compiler dependency there.
Here's a simple implementation in C++ of what you're trying to do:
struct named_or_indexed_states {
named_or_indexed_states() : speed(indexed[0], position(indexed[1]) { }
float &speed;
float &position;
float indexed[2];
};
If the size increase because of the reference elements is too much, use accessors:
struct named_or_indexed_states {
float indexed[2];
float& speed() { return indexed[0]; }
float& position() { return indexed[1]; }
};
The compiler will have no problem inlining the accessors, so reading or writing speed() and position() will be just as fast as if they were member data. You still have to write those annoying parentheses, though.
Only accessing last written member of union is well-defined; the code you presented uses, as far as only standard C (or C++) is concerned, undefined behavior - it may work, but it's wrong way to do it. It doesn't really matter that struct uses the same type as the type of array - there may be padding involved, as well as other invisible tricks used by compiler.
Some compilers, like GCC, do define it as allowed way to achieve type-punning. Now the question arises - are we talking about standard C (or C++), or GNU or any other extensions?
As for what you should use - proper conversion operators and/or constructors.
This may be a little old-fashioned, but what I would do in this situation is:
enum
{
F_POSITION,
F_SPEED,
F_COUNT
};
float states[F_COUNT];
Then you can reference them as:
states[F_POSITION] and states[F_SPEED].
That's one way that I might write this. I'm sure that there are many other possibilities.
I'm making a very simple class to represent positions in 3D space.
Currently, I'm just letting the user access and modify the individual X, Y and Z values directly. In other words, they're public member variables.
template <typename NumericType = double>
struct Position
{
NumericType X, Y, Z;
// Constructors, operators and stuff...
};
The reasoning behind this is that, because NumericType is a template parameter, I can't rely on there being a decent way to check values for sanity. (How do I know the user won't want a position to be represented with negative values?) Therefore, there's no point in adding getters or setters to complicate the interface, and direct access should be favored for its brevity.
Pos.X = Pos.Y + Pos.Z; // Versus...
Pos.SetX(Pos.GetY() + Pos.GetZ());
Is this an okay exception to good practice? Will a (hypothetical) future maintainer of my code hunt me down and punch me in the face?
The idea behind using getters and setters is to be able to perform other behavior than just setting a value. This practice is recommended because there are a multitude of things you might want to retrofit into your class.
Common reasons to use a setter (there are probably more):
Validation: not all values allowed by the type of the variable are valid for the member: validation is required before assignment.
Invariants: dependent fields might need to be adjusted (e.g. re-sizing an array might require re-allocation, not just storing the new size).
Hooks: there is extra work to perform before/after assignment, such as triggering notifications (e.g. observers/listeners are registered on the value).
Representation: the field is not stored in the format "published" as getters and setters. The field might not even stored in the object itself; the value might be forwarded to some other internal member or stored in separate components.
If you think your code will never, ever use or require any of the above, then writing getters and setters by principle is definitely not good practice. It just results in code bloat.
Edit: contrarily to popular belief, using getters and setters is unlikely to help you in changing the internal representation of the class unless these changes are minor. The presence of setters for individual members, in particular, makes this change very difficult.
Getters and setters are really only an important design choice if they get/set an abstract value that you may have implemented in any number of ways. But if your class is so straight-forward and the data members so fundamental that you need to expose them directly, then just make them public! You get a nice, cheap aggregate type without any frills and it's completely self-documenting.
If you really do want to make a data member private but still give full access to it, just make a single accessor function overloaded once as T & access() and once as const T & access() const.
Edit: In a recent project I simply used tuples for coordinates, with global accessor functions. Perhaps this could be useful:
template <typename T>
inline T cX(const std::tuple<T,T,T> & t) { return std::get<0>(t); }
typedef std::tuple<double, double, double> coords;
//template <typename T> using coords = std::tuple<T,T,T>; // if I had GCC 4.8
coords c{1.2, -3.4, 5.6};
// Now we can access cX(c), cY(c), cZ(c).
Took me a while, but I tracked this old Stroustrup interview down, where he discusses exposed-data structs versus encapsulated classes himself: http://www.artima.com/intv/goldilocks3.html
Getting more heavily into specifics, there's are dimensions to this that may be missing / understated in existing answers. The benefits of encapsulation increase with:
re-compilation/link dependency: low-level library code that is used by large numbers of applications, where those apps may be time-consuming and/or difficult to recompile and redeploy
it's usually easier if implementation was out-of-line (which may require pImpl idiom and performance compromises) so you only have to relink, and easier still if you can deploy new shared libraries and simply bounce the app
by way of contrast, there's massively less benefit from encapsulation if the object's only used in "non-extern" implementation of a specific translation unit
interface stability despite implementation volatility: code where the implementation is more experimental / volatile, but the API requirement is well understood
note that by being careful it may be possible to give direct access to member variables while using typedefs for their types, such that a proxy object can be substituted and support identical client-code usage while invoking different implementation
If you do some very easy stuff your solution could be just fine.
If you later realize that calculations in a spherical coordinate system are much easier or faster (and you need performance), you can count on that punch.
It is ok for such well known structure that :
Can have any possible values, like an int;
Should operate like a built-in type when manipulating it's value, for performance reasons.
However, if you need more than a type that "just is a 3D vector", then you should wrap it in another class, as private member, that would then expose x, y and z through member functions and additional features member functions.
The reasoning behind this is that, because NumericType is a template parameter, I can't rely on there being a decent way to check values for sanity. (How do I know the user won't want a position to be represented with negative values?)
The language and compilers support this case well (via specialization).
Therefore, there's no point in adding getters or setters to complicate the interface, and direct access should be favored for its brevity.
Moot argument -- see above.
Is this an okay exception to good practice?
I don't think it is. Your question implies validation should exist, but it's not worth implementing/supporting because you've chosen to use a template in your implementation, and not specialize appropriate for the language feature you've chosen. By that approach, the interface only appears to be partially supported -- those missing implementations will just pollute clients' implementations.