int wrapper without overloading all the operators - c++

I would like to have an int wrapper class that behaves like int without the need to overload all of the operators. The same question was asked but not really answered here. I know I can write a template wrapper and overload dozens of operators to achieve that (in fact, I have it like that now - basically it looks like this mess). However it would be nice if it would be possible to somehow expose the internal primitive type without the need to overload the operators that just forward the call to it.
Is that possible? Perhaps by overloading dereferencing operators or somesuch?
EDIT: Example code:
template<typename T>
class IDWrapper
{
public:
inline IDWrapper() { }
inline IDWrapper(T id) : m_Value(id) { }
constexpr static int size() { return sizeof(T); }
constexpr static T min() { return std::numeric_limits<T>::min(); }
constexpr static T max() { return std::numeric_limits<T>::max(); }
inline bool isValid() const { return m_Value != 0; }
inline operator T() const { return m_Value; }
inline operator T&() { return m_Value; } //this line was the attempt to make it transparent... unsuccessfully
inline IDWrapper &operator=(T v) { m_Value = v; return *this; }
inline void invalidate() { m_Value = 0; }
private:
T m_Value = 0;
};
Basically it wraps an ID of type T in a "special" way so that it gives convenient options for validating and invalidating it. Plus it gives convenient access the the size and min/max. The reason for the templated wrapper is that I will need to replace it later with base64 number or some other non-standard number type and I need the interface that relies on the IDWrapper to stay consistent. The numerical operators will still be provided by T so when I spell them out here I am just forwarding the call hence the question.

So I have fiddled with it inspired by the comments to the OP and it seems that having these two (and only these two) overloaded operators can do the trick:
operator T&() { /*...*/ }
operator const T&() const { /*...*/ }
Naturally it is not without the cost. For example if T is an int (or any type for which sizeof(T) < sizeof(void*)) then returning const reference to it is more expensive than doing a copy (but having a copy operator breaks the transparency). Not to mention memory address lookup. I am not sure about potential other problems with this so feel free to comment/answer. But this works.

Related

What is the purpose of operator RestrictedBool in QScopedPointer?

I read through the code for QScopedPointer and came across something that I haven't been able to make sense of.
Here's the pertinent code from QScopedPointer on code.qt.io:
template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
{
typedef T *QScopedPointer:: *RestrictedBool;
public:
...
#if defined(Q_QDOC)
inline operator bool() const
{
return isNull() ? Q_NULLPTR : &QScopedPointer::d;
}
#else
inline operator RestrictedBool() const
{
return isNull() ? Q_NULLPTR : &QScopedPointer::d;
}
#endif
...
inline bool isNull() const
{
return !d;
}
...
protected:
T *d;
I understand the preprocessor definition that makes QDoc think QScopedPointer has an operator bool instead of operator RestrictedBool. What I don't understand it what purpose RestrictedBool serves and how it does it. For example, a simpler implementation is:
inline operator bool() const
{
return !isNull();
}
In short: What's happening here? Why is operator RestrictedBool underhandedly returning the address of d and why does it exist in the first place instead of operator bool?
This is an implementation of the Safe Bool Idiom, explained here.
The naive implementation:
inline operator bool() const
{
return !isNull();
}
returns an rvalue of bool that can be implicitly used for other operations, e.g.
QScopedPointer<Foo> foo(nullptr);
int i = 1;
if (foo < i)
...
is valid code.
Summary: RestrictedBool is a private typedef of a pointer to the type of d. Using it as the return type for an operator means it can be used in an if statement (if (foo)), but cannot be used with other operators.
Note: C++11 allows the use of explicit operator bool, which eliminates the need for the Safe Bool Idiom in C++11 or later code. An implementation for QScopedPointer in C++11 might look like this:
explicit operator bool() const
{
return !isNull();
}
Thank you to tobi303 and Jarod42 for providing the basis for this answer.
Further reading regarding C++11 and the Safe Bool Idiom:
Chris's C++ Thoughts - Contextually converted to bool
Is the safe-bool idiom obsolete in C++11? - SO question
Very explicit operator bool - a writeup specific to QScopedPointer

Bracket Overload for Assignment and Retrieval; const, reference

Regarding overloading brackets in C++, my compiler is using the mutator method for access. Can anyone tell me why?
1. const int & Cheese::operator [] (int i)const { return weight[i]; } //accessor
2. int & Cheese::operator [] (int i) { return weight[i]; } //mutator
For example, the cout command below is using the mutator function definition--#2 above--to access the data.
Cheese cheddar;
cout << cheddar[2] << endl;
Why is this not using the first function--the accessor--to get the data? I would think that, since the cout is simply a retrieval, it would fire on the first.
How does the compiler know which of these to invoke?
EDIT: For completeness, by mutator, I mean used as a "setter," like so:
cheddar[2] = 100;
Both together would be as follows:
cheddar[2] = cheddar[1];
Where the rhs is just a "getter." It simply retrieves the value of cheddar[1], does not change anything, and thus can be const. In contrast, the lhs bracket overload cheddar[2] functions as a "setter;" the value can be changed, and function return value can't be const.
It invokes the first one for any constant instance (like const Cheese or const Cheese&) and the second one for mutable instances.
In case you care about a way you can get roughly the effect you seem to want (specifically, to have one function executed to get the value, and other code to set the value, dependably), there is a way to do that.
The usual way is to return a proxy instead of returning the value (or a reference to it) directly. The proxy overloads operator T and operator=.
template <class T>
class Proxy {
T value;
public:
Proxy(T v) : value(v) {}
// used only to get value
operator T() const { return value; }
// used only to set value
Proxy &operator=(T new_value) {
value = new_value;
return *this;
}
};
Then your overload just returns an instance of this:
Proxy<Cheese &> operator[](int i) { return Proxy<int>(weight[i]); }
Proxy<Cheese const &> operator[](int i) const { return Proxy<int>(weight[i]); }
Note that in the second case, T has the type Cheese const & and operator= isn't a const member function, so you won't be able to use operator= in this case (which is exactly what you normally want).

How do I make a class in C++, when initialized, return a boolean value when its name is invoked, but no explicit function call make, like ifstream

How do I make a class in C++, when initialized, return a Boolean value when its name is invoked, but no explicit function call make, like ifstream. I want to be able to do this:
objdef anobj();
if(anobj){
//initialize check is true
}else{
//cannot use object right now
}
not just for initialization, but a check for its ability to be used.
The way istream does it is by providing an implicit conversion to void*
http://www.cplusplus.com/reference/iostream/ios/operator_voidpt/
stream output and implicit void* cast operator function invocation
Update In reaction to the comments, the Safe Bool Idiom would be a far better solution to this: (code directly taken from that page)
class Testable {
bool ok_;
typedef void (Testable::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
public:
explicit Testable(bool b=true):ok_(b) {}
operator bool_type() const {
return ok_==true ?
&Testable::this_type_does_not_support_comparisons : 0;
}
};
template <typename T>
bool operator!=(const Testable& lhs,const T& rhs) {
lhs.this_type_does_not_support_comparisons();
return false;
}
template <typename T>
bool operator==(const Testable& lhs,const T& rhs) {
lhs.this_type_does_not_support_comparisons();
return false;
}
The article by Bjorn Karlsson contains a reusable implementation for the Safe Bool Idiom
Old sample:
For enjoyment, I still show the straight forward implementation with operator void* overloading, for clarity and also to show the problem with that:
#include <iostream>
struct myclass
{
bool m_isOk;
myclass() : m_isOk(true) { }
operator void* () const { return (void*) (m_isOk? 0x1 : 0x0); }
};
myclass instance;
int main()
{
if (instance)
std::cout << "Ok" << std::endl;
// the trouble with this:
delete instance; // no compile error !
return 0;
}
This is best accomplished using the safe bool idiom.
You provide an implicit conversion to a member-function-pointer, which allows instances of the type to be used in conditions but not implicitly convertyed to bool.
You need a (default) constructor and an operator bool()().
class X {
public:
operator bool ()const{
//... return a boolean expression
}
};
usage:
X x; // note: no brackets!
if( x ) {
....
}
You'll want to create an operator bool function (or as boost does, an unspecified_bool_type that has certain improved properties I can't recall offhand). You may also want to create operator! (For some reason I seem to recall iostreams do this too).

Is there any obvious drawback to use a no assignment swap?

I was implementing (for training purpose) a Bubble Sort template function:
template<typename iterInput,
typename predicate>
void BubbleSort(iterInput first1,iterInput last1,predicate func)
{
bool swapped(false);
do
{
swapped = false;
iterInput begin = first1;
iterInput beginMinus = first1;
++begin;
for (;begin != last1; begin++,beginMinus++)
{
if (func(*beginMinus,*begin) )
{
std::swap(*beginMinus,*begin);
swapped = true;
}
}
}
while(swapped);
}
When I have realized that this function will not work for class with no assignment operator, like this one (forgive me for the bad name):
class NoCopyable
{
public:
explicit NoCopyable(int value) : value_(value) {}
NoCopyable(const NoCopyable& other) : value_(other.value_) {}
~NoCopyable() {}
bool operator<(const NoCopyable& other) { return value_ < other.value_; }
void setValue(int value) { value_ = value; }
std::ostream& print(std::ostream& os) const { return os << value_; }
private:
NoCopyable& operator=(const NoCopyable& other);
int value_;
};
std::ostream& operator<<(std::ostream& os, const NoCopyable& obj)
{
return obj.print(os);
}
struct PrintNoCopyable
{
void operator()(const NoCopyable& noCopyable) { std::cout << noCopyable << '\n'; }
};
The compiler raises this error Error 1 error C2248: 'NoCopyable::operator =' : cannot access private member declared in class 'NoCopyable'
So, I have slightly modify the code using instead of the std::swap function my version of the swap function, here is the code:
template<typename T1,
typename T2>
void noAssignmentSwap(T1& t1,T2& t2)
{
T1 temp(t1);
t1.~T1();
new (&t1) T1(t2);
t2.~T2();
new (&t2) T2(temp);
}
The code compiles and gives the right result. However I am not completely sure, I remember a Sutter's article that suggest you to avoid playing with the objects life time. The article just warns you by playing with fire without actually giving you any real reason. I can see problem in exception safety if the copy constructor of T1 or T2 can throw. However there is the same problem in the standard version if the assignment operator is allowed to throw.
Here the question, can you see any possible drawbacks in this version of swap?
Cheers
Apart from anything else, if a class does not have an assignment operator, its designer probably did not intend it to be swapped. If they did that, they probably disabled copy construction too, so your new swap function still won't work.
As for your assertion that Standard Library containers do not need assignment - that is true so long as you don't want to actually do anything useful with them. Does this code compile for you?
#include <vector>
using namespace std;
struct A {
private:
void operator=( const A &);
};
int main() {
vector <A> v;
v.push_back( A() );
v[0] = A(); // assignment needed here
}
I think it won't.
The difference is that when the assignment operator fails, you still have the same number of objects.
If you destroy one object and fail to create a new one, one object is lost! If it was part of a container, the container's state is probably also invalid.
You need a copy ctor instead of an assignment operator, but the two are sufficiently similar that at least in a typical case, you'll have both or you'll have neither. IOW, I don't think this generally accomplishes much.
I'd class it right along side the xor-swap trick: interesting, but generally useless.
It might be confusing to a future maintainer of the code.

Const and non-const access resolves to different overloads?

Let me say we have a simple programming task. But for the sake of clarity I start with few code samples.
First of all we written a some kind of data container class but for the purposes of task no matter what the class is. We just need it to behave const-correct.
class DataComponent {
public:
const std::string& getCaption() const {
return caption;
}
void setCaption(const std::string& s) {
caption = s;
}
private:
std::string caption;
};
Then let us assume we've got a generic class that behaves like facade over arbitrary incapsulated class instance. Say we overloaded member access operator (->).
template <typename T> class Component {
public:
Component() { instance = new T(); }
...
const T* operator-> () const {
return instance;
}
T* operator-> () {
// but there might be additional magic
return instance;
}
private:
T *instance;
};
At this point I should say how I want this to work:
if we're calling non-const member functions of underlying class through member access operator (component->setCaption("foo")) compilier treats non-const T* operator-> () as the best choice.
otherwise if we are trying to call const member functions of underlying class same way (component->getCaption()) compiliers selects const T* operator-> () const on the other hand.
This code sample above won't work this way so I'm curious about possibility to give compiler a behavior like that I have mentioned. Any propositions.
EDIT: Let our member access operator overloaded this way:
const T* operator-> () const { return instance; }
T* operator-> () {
cout << "something going change" << endl;
return instance;
}
And let us have a variable Component<DataComponent> c somewhere. Then on the call to c->getCaption() stdout should remain silent but on the call to c->setCaption("foo") stdout should warn us that something is going to change. VS 2010 compilier makes stdout warn us on each of these calls.
I understand that such semantics suppose that c behaves as const and non-const at the same time. But curiousity is still in my mind.
Whether a const or non-const member is invoked is determined purely by the constness of the object on which it is invoked, not by some subsequent operation. That determination is made before any consideration of the particular method you're invoking in DataComponent. You could still hack up the required functionality less directly using proxy object around DataComponent, with both const and non-const forwarding getCaption()s.
EDIT: details as requested (off the top of my head). You'll need to forward declare some of this stuff - I didn't bother as it makes it even more confusing. Do chip in with any concerns / feedback. Note that this basically assumes you can't / don't want to modify Component for some reason, but it's not a generic templated solution that can simply be wrapped around any arbitrary type - it's very heavily coupled and has a high maintenance burden.
// know they can't call a non-const operation on T, so this is ok...
const T* Component::operator->() const { return instance; }
// they might invoke a non-const operation on T, so...
DataComponent::Proxy Component::operator->() { return DataComponent.getProxy(*this); }
in class DataComponent:
struct Proxy
{
Component& c_;
DataComponent& d_;
Proxy(Component& c, DataComponent& d) : c_(c), d_(d) { }
const std::string& get_caption() const { return d_.get_caption(); }
void set_caption(const std::string& s)
{
c_.on_pre_mutator(d_);
d_.set_caption(s);
c_.on_post_mutator(d_);
}
};
then
DataComponent::Proxy DataComponent::getProxy(Component& c) { return Proxy(c, *this); }
So, this means somewhere you have to hand-code forwarding functions. It's a pain, but if you're doing this for debugging or testing it's not unreasonable. If you're doing this so you can add a lock or something, then there are probably better alternatives.