Trying to find a "simple to use" safe_bool idiom/implementation, I've ended up with my own.
Q: Is this implementation correct?
template <typename T>
class safe_bool
{
protected:
typedef void (safe_bool::*bool_type)() const;
bool_type to_bool_type(bool b) const
{ return b ? &safe_bool<T>::safe_bool_true : 0; }
private:
void safe_bool_true() const {}
private:
bool operator ==(safe_bool<T> const & rhs);
bool operator !=(safe_bool<T> const & rhs);
};
to be used like this:
struct A : public safe_bool<A>
{
// operator bool() const { return true; }
operator bool_type() const { return to_bool_type(true); }
};
The only addition to existing base classes would be to_bool_type, but I hope I've got everything else correct, too.
The test cases I used (VC9) can be found here.
The downsides I see in implementation: bool_type and to_bool_type are visible in derived classes, which might not appease to everyone. Also, using the wrong template argument (e.g. class B : public safe_bool<A> introduced during copy-and-paste) will go unnoticed.
The “wrong template argument” problem you mentioned is almost completely eliminated by the static_cast in the wikibooks.org solution (“for testability without virtual functions”) cited by #Terry Mahaffey. The only thing I can see wrong with their solution is the separate safe_bool_base class, which will suppress the empty base optimization when it appears in multiple base classes (or elements in a compressed_pair). Personally, I'd move that implementation back up into the template.
Using a pointer to a member function as the bool alias is idiomatic, as you're doing here.
Your implementation looks correct for what is there, but slightly incomplete. See http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool
IMO safe_bool falls into the category of things which do more harm than good; ie the complexity and confusion introduced by this idiom along with the mental effort needed to understand it are greater than the intial problem it is intending to solve.
Related
apologies in advance if this question is stupid but:
I have an interface:
template <class T>
class IEqualCompare {
public:
virtual bool IsEqual(const T b) = 0;
bool operator== (const T b) { return this->IsEqual(b); } //Both are implemented in cpp file
bool operator!= (const T b) { return !(this->IsEqual(b)); }
};
And a class:
class Dimentions : IEqualCompare<Dimentions> {
...
bool IsEqual(const Dimentions b) { //IsEqual logic for this specific class }
...
}
I would like to only implement IsEqual method for each child class of IEqualCompare, as the logic within the operator overloads (==, !=) is the same for any IEqualCompare derived class.
Up until now I have always simply defined both operator overrides as virtual and implemented them inside each class, but as the logic should be always the same I wanted to know if this is possible or is it bad programming.
Thanks in advance for any answers.
First of all, since comparison operators are usually not meant to modify compared objects, they (and IsEqual method) should be declared const as a general practice of const correctness. Among other things it helps programmers avoid mistakes of accidentally modifying objects during semantically non-modifying operations and helps optimizers produce more efficient binaries by utilizing more assumptions about code behaviour. Also, to avoid unnecessary copying the argument of operators should generally be taken by reference, in our case by const reference so that referenced object can't be modified.
Now, if you want to just automatically add equality comparison operators to derived classes based on their IsEqual method and not to use dynamic polymorphism/dispatch (it would be pretty pointless for CRTP base), there's no need to make IsEqual virtual, or even a member of base class at all. Derived type is provided as template parameter type T, so you statically know actual (dynamic) object type (this is the whole point of CRTP pattern you use), thus you can statically cast this pointer to T* and call non-virtual IsEqual method of T through resulting pointer avoiding the more costly virtual dispatch mechanism. Example:
template<typename T>
class AddEqualComparisons {
public:
bool operator==(const T& b) const { return static_cast<T*>(this)->IsEqual(b); }
bool operator!=(const T& b) const { return !static_cast<T*>(this)->IsEqual(b); }
};
class Dimensions : public AddEqualComparisons<Dimensions> {
bool IsEqual(const Dimensions& rhs) const {
// ...
}
};
Your solution is not necessarily bad, it is an application of the "template method" design pattern. It does read like C#/Java-style code to me, which is perhaps unconventional in C++ for this purpose.
The convention in C++ has been to just write each operator!= in terms of operator==. With compilers now supporting C++20, the complementary operator can be generated automatically, removing the need to write a trivial expression like !(x == y). Something like this is often all you need to make your class equality-comparable:
class Foo {
friend bool operator==(Foo const&, Foo const&) = default;
};
If the subobjects of the class (its base classes and member variables) are all equality_comparable, then the above syntax will produce a default comparison operator that compares the two sets of subobjects. You can of course create your own definition if you need to deviate from this.
Note that declaring the operator as a non-member friend function is just my preference, the member function syntax is equally valid.
I am working with an existing C library (that I can't modify) where some structures have opaque fields that must be accessed through specific setters and getters, like in the following crude example (imagining x is private, even though it's written in C).
struct CObject {
int x;
};
void setCObjectX(CObject* o, int x) {
o->x = x;
}
int getCObjectX(CObject* o) {
return o->x;
}
I am writing classes that privately own these types of structures, kind of like wrappers, albeit more complex. I want to expose the relevant fields in a convenient way. At first, I was simply writing setters and getters wherever necessary. However, I thought of something else, and I wanted to know if there are any downsides to the method. It uses function pointers (std::function) to store the C setter-getter pairs and present them as if directly accessing a field instead of functions.
Here is the generic class I wrote to help define such "fake" fields:
template<typename T>
struct IndirectField {
void operator=(const T& value) {
setter(value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter();
}
std::function<void(const T&)> setter;
std::function<T()> getter;
};
It is used by defining an instance in the C++ class and setting up setter and getter with the corresponding C functions:
IndirectField<int> x;
// ...
x.setter = [=](int x) {
setCObjectX(innerObject.get(), x);
};
x.getter = [=]() {
return getCObjectX(innerObject.get());
};
Here is a complete, working code for testing.
Are there any disadvantages to using this method? Could it lead to eventual dangerous behaviors or something?
The biggest problem I see with your solution is that std::function objects take space inside each instance of IndirectField inside CPPObject, even when CObject type is the same.
You can fix this problem by making function pointers into template parameters:
template<typename T,typename R,void setter(R*,T),T getter(R*)>
struct IndirectField {
IndirectField(R *obj) : obj(obj) {
}
void operator=(const T& value) {
setter(obj, value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter(obj);
}
private:
R *obj;
};
Here is how to use this implementation:
class CPPObject {
std::unique_ptr<CObject,decltype(&freeCObject)> obj;
public:
CPPObject()
: obj(createCObject(), freeCObject)
, x(obj.get())
, y(obj.get()) {
}
IndirectField<int,CObject,setCObjectX,getCObjectX> x;
IndirectField<double,CObject,setCObjectY,getCObjectY> y;
};
This approach trades two std::function objects for one CObject* pointer per IndirectField. Unfortunately, storing this pointer is required, because you cannot get it from the context inside the template.
Your modified demo.
Are there any disadvantages to using this method?
There's a few things to highlight in your code:
Your getters & setters, being not part of the class, break encapsulation. (Do you really want to tie yourself permanently to this library?)
Your example shows a massive amount of copying being done; which will be slower than it needs to be. (auto operator()(), operator T() to name but 2).
It's taking up more memory than you need to and adds more compexity than just passing around a Cobject. If you don't want things to know that it's a CObject, then create an abstract class and pass that abstract class around (see below for example).
Could it lead to eventual dangerous behaviors or something?
The breaking of encapsulation will result in x changing from any number of routes; and force other things to know about how it's stored in the object. Which is bad.
The creation of IndirectField Means that every object will have to have getters and setters in this way; which is going to be a maintenance nightmare.
Really I think what you're looking for is something like:
struct xProvider {
virtual int getX() const = 0;
virtual void setX() = 0;
};
struct MyCObject : xProvider {
private:
CObject obj;
public:
int getX() const override {return obj.x;}
CObject& getRawObj() {return obj;}
// etc ...
}
And then you just pass a reference / pointer to an xProvider around.
This will remove the dependence on this external C library; allowing you to replace it with your own test struct or a whole new library if you see fit; without having to re-write all your code using it
in a struct by default (as you post) all the fields are public, so they are accessible by client software. I you want to make them accessible to derived classes (you don't need to reimplement anything if you know the field contract and want to access it in a well defined way) they are made protected. And if you want them to be accessed by nobody, then mark them as private.
If the author of such a software doesn't want the fields to be touched by you, he will mark them as private, and then you'll have nothing to do, but to adapt to this behaviour. Failing to do will give you bad consequences.
Suppose you make a field that is modified with a set_myField() method, that calls a list of listeners anytime you make a change. If you bypass the method accessing function, all the listeners (many of them of unknown origin) will be bypassed and won't be notified of the field change. This is quite common in object programming, so you must obey the rules the authors impose to you.
EDIT: To be clear—right off the bat—this is a question about the linguistic abilities of a modern C++ compiler. Not a question about a specific goal. It's hard to describe such an abstract concept without clarifying this first and I've realized that some of the confusion revolves around what is commonly done rather than what can possibly be done. This is a very abstract question. Nothing here will compile and this is on purpose. Likewise, I'm not asking how to make this specific case work, but I'm asking if there's a way to get C++ to recognize what I would like to do (via templating or some kind of auto->decltype trick most likely if even possible).
I'm not exactly new to C++, but certainly not an expert. This is a fundamental problem that I've been struggling with since I've rediscovered the power of the language. The end goal here is to elegantly (and with as little code as possible) forward proper polymorphic return values based on calling context. For example...
class A {
public:
A& foo() {
// do something mutant fooish
return *this;
};
};
class B: public A {
public:
B& bar() {
// do something mutant barish
return *this;
};
};
int main(int argc, char** argv) {
B yarp;
yarp.foo().bar();
};
Compile error. Makes sense, C++ is designed to assume that you know nothing about what you're doing (which makes it highly optimizable but sometimes a pain... a high-level-mid-level OOP language).
Obvioiusly C++ compilers have gotten to the point where they're not only aware of what you are asking for (the A().foo() works and B().foo() works scenario), but also in what context your asking for it in (hence auto yarp = B() in C++11, the compiler knows that yarp is an instance of B). Is there a way to leverage this elegantly without having to reproduce a bunch of "using" statements or wrapped methods (which strangely don't get optimized out according to disassemble of gcc binaries)?
So is there a trick here? Something I simply haven't learned online. An auto -> decltype trick or a templating trick? Example:
class A {
public:
template <typename R>
R& foo() {
// do something fooish
return (R&)*this;
};
};
class B: public A {
public:
using A::foo<A>; // << even this would be better than nothing (but no where near optimum)
B& bar() {
// do something barish
return *this;
};
};
Something even simpler? If you expand this concept to operators of a proxy template class meant for reference counting and gc deallocation, it becomes clear how problematic this becomes. Thanks in advance for any help (oh, and first post on stackoverflow, so if I got any formatting wrong or you have suggestions for a better structured post, apologies around and please point them out).
The obvious solution would be to just seperate it out into two lines:
yarp.foo();
yarp.bar();
or, alternatively, use static_cast's to get back a reference to B&, so
static_cast<B&>(yarp.foo()).bar();
Agreed, that's a little bit more verbose but chaining multiple member-function calls in a heirarchy in one line together like this is pretty unusual syntax for C++. It just doesn't come up a whole lot, so the language doesn't support that idiom terribly well. I have never come across a situation where I ran into this issue yet.
If you want to design some chainable functionality, there are other, better idioms you can use. One example is Boost's Range Adaptors that overload operator| to achieve chaining.
EDIT: Another option is to overload foo() in B&:
class B: public A {
public:
B& foo() { A::foo(); return *this; }
B& bar() {
// do something mutant barish
return *this;
};
};
I don't think there is a auto type detection since compiler even doesn't know what classes will inherit A.
And in your second trial, C++ forbid using a template specialization. So that won't compile.
I think there is another trick you could try is to make A a template
template <typename FinalType>
class A {
public:
FinalType& foo() {
// do something fooish
return static_cast<FinalType&>(*this);
};
};
class B: public A<B> {
public:
B& bar() {
// do something barish
return *this;
};
};
Erm you declare a instance of class B which has no method foo - so no wonder there is a compile error - did you mean
yarp.bar().foo();
I have the following struct:
template <typename T>
struct Odp
{
T m_t;
};
I want to specialize it so I can add an operator so the type plays nicely with STL sets. (I can't modify Odp directly; it's legacy code.) Here are two methods I see of doing it:
struct Ftw : public Odp<int>
{
bool operator==(const Ftw& rhs)
{
return m_t == rhs.m_t;
}
};
struct FtwContain
{
Odp<int> odp;
bool operator==(const FtwContain& rhs)
{
return odp.m_t == rhs.odp.m_t;
}
};
Is there any reason to prefer the second over the first? The first method appears to allow cleaner code:
Ftw ftw;
ftw.m_t = 2;
FtwContain ftwContain;
ftwContain.odp.m_t = 2;
(Also, there's a chance that I'm confused about what the term "template specialization" means.)
I don't believe there is any need to create a new type - simply write a free function:
template <typename T>
bool operator==( const Odp<T> & a, const Odp <T> & b ) {
return a.m_t == b.m_t;
}
You may indeed be confused about the terminilogy. (Partial) template specialization normally referes to a specific implementation of a templated class /struct for a dedicated type. I.e. you may have a generic template class Hash that provides hash values for types using a method getHash. This method then has a generic implementation, that doesn't care about the type, and maybe a special implementation for hash values on strings:
// default implementation
template<typename T> class Hash { int getHash(T val) { return val; } }
// string implementation
template<> class Hash<std::string> { int getHash(std::string val) { return val[0] || val[1]; } }
What you are doing in ur examples however is not template specialization but inheritance (in the first approach) and using the Odp template as a client. In both cases, if anyone uses the Odp template as in Odp<int> odp, the original implementation will be used, which may not be what you want. If you would use proper template specialization, Odp<int> would refer to your specialized code.
Why not deriving Odp to MyOdp, put your (generic) code in it and just make Ftw derive from Odp (as in your first example) or using a typedef ?
By the way that not specialization but instanciation. Template specialization is when you (re)define a method for a specific type.
I usually prefer composition over inheritance, but it really depends on the design. Is Ftw a type of Odp or does Ftw contain an Odp.
I wouldn't choose the method based on cleaner code (since it's not that much of a difference), I would choose the method based on conceptually what is the relationship between Odp and Ftw.
In the case you mentioned, I think a free function is possibly the cleanest way with the least amount of rebuild issues. Put this free function in a separate cpp file and you should be good to go.
Possible cases for derivation
You would want to derive if you have to pass your object to some function which takes a base-class type
Is the derived class a type of the first type. If so, yes (eg., a carnivore is an animal)
3.If there are protected methods in the base class that you want to use in your derived class. I am not sure if the structure you mentioned is the complete code or only the relevant section. If it is not, then this might be one reason you want to derive.
Possible cases for containing
You merely want to use the class and there is no is-a relationship. TBH, one can simulate an is-a with containing objects too, where in the container type acts like a proxy for the contained-type (I think this is a design pattern, but am not sure of the name of the pattern).
You are interested in using only one or two methods, and there is no worry of a shared state
This object is never passed to any other interface which requires a base class (one can always pass the contained object, but that looks dirty. Also, toss in virtual functions and things are different. Sorry, I digress).
As Neil mentions, operator== can well be a free function.
Another option: standard library allows the use of custom predicate objects. In this case:
#include <set>
template <typename T>
struct Odp
{
T m_t;
};
struct CompareOdp
{
template <class T>
bool operator() (const Odp<T>& a, const Odp<T>& b) const
{
return a.m_t < b.m_t;
}
};
int main()
{
std::set<Odp<int>, CompareOdp > my_set;
Odp<int> value = {10};
my_set.find(value);
}
(Not sure, whether it might be a better idea to make the whole predicate a template. Making just operator() a template seems to make it easier to use, as it leaves more things to the compiler to figure out. Not sure if it could back-fire in some scenarios.)
Also note that std::set uses a predicate for ordering (by default std::less<X>), not for equality tests.
I was reading this morning the book The Pragmatic Programmer Chapter 3 on Basic Tools every programmer should have and they mentioned Code Generation Tools.
They mentioned one Perl script for C++ programs which helped automate the process of implementing the get/set() member functions for private data members.
Does anyone know about such a script and where to find it? I've been unable to come up with the right google keywords to find it.
Although it doesn't directly answer your question, you may find that generated code is actually unnecessary for managing properties in C++. The following template code will allow you to declare and use properties conveniently:
// Declare your class containing a few properties
class my_class {
public:
property<int> x;
property<string> y;
...
};
...
my_class obj;
cout << obj.x(); // Get
obj.y("Hello, world!"); // Set
Here is the code:
// Utility template to choose the 2nd type if the 1st is void
template <typename T, typename U>
struct replace_void {
typedef T type;
};
template <typename T>
struct replace_void<void, T> {
typedef T type;
};
// Getter/setter template
template <typename T, typename D = void>
class property {
typedef typename replace_void<D, property>::type derived_type;
derived_type& derived() { return static_cast<derived_type&>(*this); }
public:
property() {} // May be safer to omit the default ctor
explicit property(T const& v) : _v(v) {}
property(property const& p) : _v(p._v) {}
property& operator=(property const& p) { _v = p._v; return *this; }
T operator()() const { return _v; } // Getter
void operator()(T const& v) { derived().check(v); _v = v; } // Setter
protected:
// Default no-op check (derive to override)
void check(T const& v) const { (void)v; //avoid unused variable warning}
private:
T _v;
};
check() is a function that tests whether the value being assigned is valid. You can override it in a subclass:
class nonnegative_int : public property<int, nonnegative_int> {
public:
// Have to redeclare all relevant ctors unfortunately :(
nonnegative_int(int v) : property<int, nonnegative_int>(v) {}
void check(int const& v) const {
if (v < 0) {
throw "Yikes! A negative integer!";
}
}
};
There you have it -- all of the advantages of externally-generated getter/setter functions, with none of the mess! :)
You could choose to have check() return a bool indicating validity instead of throwing an exception. And you could in principle add a similar method, access(), for catching read references to the property.
EDIT: As Mr. Fooz notes in the comments, the class author can later change the implementation without modifying the logical structure of the class (e.g. by replacing the property<int> x member with a pair of x() methods), although binary compatibility is lost so users will need to recompile their client code whenever such a change is made. This ability to painlessly incorporate future changes is actually the main reason people use getter/setter functions instead of public members in the first place.
Performance note: Because we are using the CRTP to achieve "compile-time polymorphism", there is no virtual-call overhead for providing your own check() in a subclass, and you need not declare it virtual.
As most C++ private members should not be accesible via Get/Set style functions, this seems like a bad idea.
For a simple example of why this is so, consider the C++ std::string class. Its private members probably look something like this (exact implementation not important):
private:
int last, len;
char * data;
Do you believe it makes any sense to provide get/set members for those?
I can't help you with the location of that particular script. However, there are quite a lot of code generation tools. You may even have what you are looking for already part of your IDE. For more debate/input on how, why, and whether to use code generation tools, you might look at this stackoverflow question. I like the accepted answer on that question.
You want a script to generate get/set functions for all of your private members indiscriminately? That wouldn't be a very useful script; you probably no going to find it in Google. If you want to be able to somehow tag your member variable and have getter and/or setter skeletons automatically generated for you, than a IDE macro seems more appropriate. Try Google for that.
I know of one programmer who uses Perl to augment the C preprocessor when it comes to macros (latest version of that project). The basic idea is you would decide on some convention to tell your Perl script when to generate a getter or setter:
struct My_struct {
//set
//get
int x;
int y;
//get
int z;
};
Given code like this, I could write a script to look for comment lines consisting of the comment "get" or "set" on the line(s) before a member variable declaration, and then replace them with simple setters/getters. In the above example I would generate void set_x(int i), int get_x(), and int get_z() after the associated member variable definitions.
A word of warning: do not do this in-place with s///. Instead, scan each line individually, and if you find an appropriate comment line push something that says "I need a getter/setter" onto a stack, then when you see the associated member variable, pop things off of the stack and generate the code.
There are a few devils in the details, but overall that is the idea.