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.
Related
I was thinking of the following scenario:
class A {
private:
std::string id;
std::array<std::string, 128> data;
public:
A(const std::string& id) : id(id) {}
A(const A& other) : id(other.id), data(other.data) {}
virtual ~A(){}
//to override the intern data
A& operator=(const A& other) {
this->data = other.data;
return *this;
}
//to override the whole element
A& operator()(const A& other) {
this->id = other.id;
this->data = other.data;
return *this;
}
};
As you can see, my idea was to use operator= to override the internal data and operator() to override the whole element. I was inspired by the constructor which would allow A a(anOtherA); to construct the element and I would like to override this for a re-construction. Now I don't now if this would be smart overloading this because it's actually the function call operator.
Is overloading operator() for a reconstruction a good practice?
In short no, that isn't good practice. Such just obfuscates what is done under the hood.
Providing a setter for data and use the code you provided in your overloaded operator() for the implementation of the assignment operator=() would provide the clearer and naturally expected semantics:
class A {
private:
std::string id;
std::array<std::string, 128> data;
public:
A(const std::string& id) : id(id) {}
A(const A& other) : id(other.id), data(other.data) {}
~A(){}
//to override the intern data
A& operator=(const A& other) {
id = other.id;
data = other.data;
return *this;
}
//to override the intern data
void setData(const A& other) {
data = other.data;
}
void setData(const std::array<std::string, 128>& data_) {
data = data_;
}
};
The semantics of the operator() isn't that clearly defined (vs the operator=()) beyond you can make a call of your class looking like a "normal" function call (which is mostly useful with templates taking your type as a parameter).
But I'd expect it more to do some action instead of changing the internal state of the class.
Regarding the style, instead of the set / get prefixes for getter/setter functions I prefer what's done in the c++ standard library, (like e.g. with the std::ios_base::flags() property):
class A {
private:
// ...
std::array<std::string, 128> data_;
public:
const std::array<std::string, 128>& data() const {
return data_;
}
void data(const std::array<std::string, 128>& data) {
data_ = data;
}
// ...
};
great answer from πάντα ῥεῖ so please upvote that answer, not this one.
As you write, and more importantly, read more c++ you will come to appreciate people who name methods and functions with natural, meaningful names.
For most of us, if we see code like this:
X x;
Y y;
x(y);
We would think, before even looking at the declarations of X and Y, that X is some kind of function object (i.e. it does something) and Y is some kind of data or state object - it likes having things done to it, or it supplies data or services.
As a side note, a Haskell programmer would naturally assume that Y is also a function, but that's another story.
If your implementation of X::operator()(Y) does not "do X-type stuff with or to a Y" then it is probably inappropriately named.
If Y actually represents new state for X, and X intends to 'reset' itself using the data in Y, then the method should probably be called... reset:
X x;
Y y;
x.reset(y); //ok, this is telling a better story
With reasonable names we can tell a narrative with our code:
void processResults(XFactory& factory, std::istream& is) {
while(is) {
auto x = X::createFrom(factory);
x.collectNResults(is, 10);
auto a = x.takeAverage();
storeAverage(a);
x.reset(y);
}
}
Now even without looking up the definitions of the various classes I can get a sense of the general narrative. It's easier on the eye and I'm going to be able to hone in on the bits I need to see much more quickly than:
void processResults(XFactory& factory, std::istream& is) {
while(is) {
auto x = X(factory);
x(is, 10);
auto a = x();
x(averageStore);
x(y);
}
}
Which is what I'd have if I wrote every operation on an X in terms of a call operator which, much like corporate tax avoidance, is actually perfectly legal, but nevertheless happens to upset other people because they end up paying the price for your selfishness.
I need to find a way to test my exception handling in a function I wrote called hpx::parallel::copy. Other functions in the library such as hpx::parallel::transform are easy to test as a predicate can be passed in which throws an exception, but copy takes no predicate.
I think my best solution would be to use an iterator that throws on dereference somehow, though I'm not quite sure how to go about doing this......any other suggestions to solving this problem are welcome as well. Here is a code example of my problem
//transform.cpp , testing exceptions
bool caught_exception = false;
try {
base_iterator outiter = hpx::parallel::transform(policy,
iterator(boost::begin(c)), iterator(boost::end(c)), boost::begin(d),
[](std::size_t v) { //easy, predicate can be passed
throw std::runtime_error("test");
return v;
});
HPX_TEST(false);
}
//catching exceptions etc...
//copy.cpp, testing exceptions
bool caught_exception = false;
try {
base_iterator outiter = hpx::parallel::copy(policy,
iterator(boost::begin(c)), iterator(boost::end(c)), boost::begin(d)); //no predicate... how can I throw?
HPX_TEST(false);
}
//catching exceptions etc..
to be more specific, I want to be able to modify what exactly I want to throw in order to test multiple scenarios, this just means I can't use an implementation that throws out of range or other exceptions I can't control, I need to throw specific exceptions.
An approach different from constructing your own iterators would be to construct a decorator class of an already existing iterator class. A toy example may be:
#include<functional>
/**
* #brief Decorates an iterator to permit code injection before dereferencing
*/
template<class T>
struct IteratorDecorator : public T {
template<class V>
IteratorDecorator(T iterator, V f) : T(iterator) , m_callback(f) {}
typename T::value_type & operator*() {
m_callback();
return T::operator*();
}
private:
std::function<void()> m_callback;
};
/**
* #brief Convenience function just for type deduction
*/
template<class T, class V>
IteratorDecorator<T> decorate(T iterator, V v) {
return IteratorDecorator<T>(iterator,v);
}
This may be used in client code like this:
int main()
{
vector<int> ivec {1, 3, 5, 6};
try {
for_each(ivec.begin(),ivec.end(),[](int& x){ cout << x << endl; } );
for_each(decorate(ivec.begin(), [](){ cout << "decorated : "; }),
decorate(ivec.end() , [](){}),
[](int& x){ cout << x << endl; });
for_each(decorate(ivec.begin(), [](){ throw runtime_error("This one throws"); }),
decorate(ivec.end() , [](){}),
[](int& x){ cout << x << endl; } );
} catch( exception& e) {
cout << e.what() << endl;
}
return 0;
}
If you want to experiment with the code, you can find a working version here.
The easiest approach is to construct your iterators with a back-reference to the container they iterate over. Whenever you increment the container's end(), or decrement its begin(), or when you dereference anything outside the container's range, you throw an exception. Because the iterator has a reference to the container, you have all this information. The overhead is a simple reference (or pointer) per iterator, and a small amount of logic in the operator--, operator++ and operator*.
Microsoft use such an approach in their Checked Iterators which you can turn on when using their Standard Library. A sample implementation is given in SafeSTL. E.g. their vector<T> looks a bit like this:
template<class T>
class vector
{
public:
class iterator
{
public:
// regular iterator interface
private:
std::vector<T>* owner; // used by implementation to do checking
};
// rest of vector<T> interface
};
Or you could do the simplest possible thing and write a value type whose copy assignment operator throws (and/or move assignment operator, copy and move constructors,...).
Since you populate the container in the first place, you can even select which values throw, if you want. There's a lot less boilerplate than writing an iterator.
NB. I'm assuming you want to test your algorithm by forcing an exception. I think TemplateRex's suggestion is aimed more at iterators which catch accidental misuse at runtime. Feel free to clarify.
Sample implementations:
The simplest possible value type - it doesn't have any actual value, and always throws on copy or move:
struct TrivialThrowOnCopy {
TrivialThrowOnCopy() = default;
TrivialThrowOnCopy(TrivialThrowOnCopy const &) {
throw std::runtime_error("copy");
}
TrivialThrowOnCopy(TrivialThrowOnCopy&&) {
throw std::runtime_error("move");
}
};
Or you could have one where you explicitly tell each instance whether to throw or not:
struct ConfigurableThrowOnCopy {
bool should_throw_;
explicit ConfigurableThrowOnCopy(bool b = false) : should_throw_(b) {}
ConfigurableThrowOnCopy(ConfigurableThrowOnCopy const &other)
: should_throw_(other.should_throw_) {
if (should_throw_) throw std::runtime_error("copy");
}
ConfigurableThrowOnCopy(ConfigurableThrowOnCopy &&other)
: should_throw_(other.should_throw_) {
if (should_throw_) throw std::runtime_error("move");
}
};
or one where every _n_th copy throws:
struct CountingThrowOnCopy {
static unsigned counter;
// set CountingThrowOnCopy::counter = 5 to make the 5th copy throw
CountingThrowOnCopy() = default;
CountingThrowOnCopy(ConfigurableThrowOnCopy const &) {
if (!--counter) throw std::runtime_error("copy");
}
CountingThrowOnCopy(ConfigurableThrowOnCopy&&) {
if (!--counter) throw std::runtime_error("move");
}
};
or any of the above but wrapping an actual value:
template <typename T>
struct ConfigurableThrowOnCopyT {
T value_;
bool should_throw_;
explicit ConfigurableThrowOnCopyT(T const &t, bool b = false)
: value_(t), should_throw_(b) {}
ConfigurableThrowOnCopyT(ConfigurableThrowOnCopyT const &other)
: value_(other.value_), should_throw_(other.should_throw_) {
if (should_throw_) throw std::runtime_error("copy");
}
ConfigurableThrowOnCopyT(ConfigurableThrowOnCopyT &&other)
: value(std::move(other.value_)), should_throw_(other.should_throw_) {
if (should_throw_) throw std::runtime_error("move");
}
T& operator() { return value_; }
T const& operator() const { return value_; }
};
As I understand copy-and-swap idiom, it has a drawback of needing of bolierplate code. Consider a simple "just-hold-all-those-damn-lemons" struct:
struct MuchData {
private:
std::string one, two;
int three;
std::vector<Something> four;
MyType five;
MyOtherType six, seven;
unsigned long long int still_overflows;
public:
MuchData() : one("."), two("/"), three(0), four(), five(), six(-1), seven(0), still_overflows(0)
{ }
MuchData(const MuchData& rhs) : one(rhs.one), two(rhs.two), three(rhs.three), four(rhs.four), five(rhs.five), six(rhs.six), seven(rhs.seven), still_overflows(rhs.still_overflows)
{ }
MuchData(MushData&& old) : one("."), two("/"), three(0), four(), five(), six(-1), seven(0), still_overflows(0)
{ swap(*this, old); }
MuchData& operator=(MuchData old) { swap(*old, this); return *this; }
friend void swap(MuchData& left, MushData&right) {
using std::swap;
swap(left.one, right.one);
swap(left.two, right.two);
swap(left.three, right.three);
swap(left.four, right.four);
swap(left.five, right.five);
swap(left.six, right.six);
swap(left.seven, right.seven);
swap(left.still_overflows, right.still_overflows);
}
// And now we can go and do something interesting
};
With initializers written in
: one(".")
, two("/")
, three(0)
// etc.
style, this code takes even more space. And MyType and MyOtherType are probably defined with this technique as well... is there any way to reduce the amount of repetitiveness here? When new fields are added, for example, it's extremely easy to forget to add the corresponding swap(...) line, which causes a mysterious slicing.
One thing you could do is store the members in a std::tuple and provide named accessors fot them, like this:
struct MuchData {
private:
std::tuple<std::string, std::string, int, std::vector<Something>, MyType, MyOtherType, unisgned long long> data;
std::string& one() { return std::get<0>(data); }
const std::string& one() const { return std::get<0>(data); }
//etc.
};
Yes, you're trading one piece of boilerplate for another, but you will only be writing the names once; the constructor syntax will be much more concise, for example. And even if you forget to add an accessor, swap() will work just fine (as it will just swap() the tuples).
With C++1y, you can even use auto& and const auto& for the return type of the accessors, eliminating even more duplication.
You can use in-class initializers to reduce duplication between constructors that initialize fields to their standard values:
class MuchData {
std::string one{"."};
std::string two{"/"};
// ...
Then the default and move constructor become trivial.
MuchData() = default;
MuchData(MuchData&& o) { swap(*this, o); }
And you can default the copy constructor:
MuchData(const MuchData&) = default;
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).
Edit1: I realize this is hard to understand this question without having an insight of what I'm trying to do. The class A is not complete but it essentially stand for a C-array "proxy" (or "viewer" or "sampler"). One interesting usage is too present a C-array as a 2d grid (the relevant function are not shown here). The property of this class are the following:
it should not own the data - no deep copyy
it should be copyable/assignable
it should be lightweight (
it should preserve constness (I'm having trouble with this one)
Please do not question the purpose or the design: they are the hypothesis of the question.
First some code:
class A
{
private:
float* m_pt;
public:
A(float* pt)
:m_pt(pt)
{}
const float* get() const
{
return m_pt;
}
void set(float pt)
{
*m_pt = pt;
}
};
void gfi()
{
float value = 1.0f;
const A ac(&value);
std::cout<<(*ac.get())<<std::endl;
A a = ac;
a.set(2.0f);
std::cout<<(*ac.get())<<std::endl;
}
Calling "gfi" generate the following output:
1
2
Assigning a with ac is a cheap way to shortcut the constness of ac.
Is there a better way to protect the value which m_pt point at?
Note that I DO want my class to be copyable/assignable, I just don't want it to loose its constness in the process.
Edit0: I also DO want to have a pointer in there, and no deep copy please (let say the pointer can be a gigantic array).
Edit2: thanks to the answers, I came to the conclusion that a "const constructor" would be a useful thing to have (at least in this context). I looked it up and of course I'm not the same one who reached this conclusion. Here's an interesting discussion:
http://www.rhinocerus.net/forum/language-c-moderated/569757-const-constructor.html
Edit3: Finally got something which I'm happy with. Thanks for your help. Further feedback is more than welcome
template<typename T>
class proxy
{
public:
typedef T elem_t;
typedef typename boost::remove_const<T>::type elem_unconst_t;
typedef typename boost::add_const<T>::type elem_const_t;
public:
elem_t* m_data;
public:
proxy(elem_t* data = 0)
:m_data(data)
{}
operator proxy<elem_const_t>()
{
return proxy<elem_const_t>(m_data);
}
}; // end of class proxy
void test()
{
int i = 3;
proxy<int> a(&i);
proxy<int> b(&i);
proxy<const int> ac(&i);
proxy<const int> bc(&i);
proxy<const int> cc = a;
a=b;
ac=bc;
ac=a;
//a=ac; // error C2679: binary '=' : no operator found which takes a right-hand operand of type...
//ac.m_data[0]=2; // error C3892: 'ac' : you cannot assign to a variable that is const
a.m_data[0]=2;
}
Your class is badly designed:
it should use float values, not pointers
if you want to use pointers, you probably need to allocate them dynamically
and then you need to give your class a copy constructor and assignment operator (and a destructor) , which will solve the problem
Alternatively, you should prevent copying and assignment by making the copy constructor and assignment op private and then not implementing them.
You can trick around with proxy pattern and additional run-time constness boolean member. But first, please tell us why.
Effectively your class is like an iterator that can only see one value. It does not encapsulate your data just points to it.
The problem you are facing has been solved for iterators you should read some documentation on creating your own iterator and const_iterator pairs to see how to do this.
Note: in general a const iterator is an iterator that cannot be incremented/decremented but can change the value it points to. Where as a const_iterator is a different class that can be incremented/decremented but the value it points to cannot be changed.
This is the same as the difference between const float * and float *const. In your case A is the same as float * and const A is the same as float *const.
To me your choices seem to be:
Encapsulate your data.
Create a separate const_A class like iterators do
Create your own copy constructor that does not allow copies of const A eg with a signature of A(A & a);
EDIT: considering this question some more, I think you are misinterpreting the effect of const-correctness on member pointers. Consider the following surprising example:
//--------------------------------------------------------------------------------
class CNotSoConstPointer
{
float *mp_value;
public:
CNotSoConstPointer(float *ip_value) : mp_value(ip_value) {}
void ModifyWithConst(float i_value) const
{
mp_value[0] = i_value;
}
float GetValue() const
{
return mp_value[0];
}
};
//--------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
float value = 12;
const CNotSoConstPointer b(&value);
std::cout << b.GetValue() << std::endl;
b.ModifyWithConst(15);
std::cout << b.GetValue() << std::endl;
while(!_kbhit()) {}
return 0;
}
This will output 12 and then 15, without ever being "clever" about the const-correctness of the const not-so-const object. The reason is that only the pointer ITSELF is const, not the memory it points to.
If the latter is what you want, you'll need a lot more wrapping to get the behavior you want, like in my original suggestion below or Iain suggestion.
ORIGINAL ANSWER:
You could create a template for your array-proxy, specialized on const-arrays for the const version. The specialized version would have a const *m_pt, return a const pointer, throw an error when you try to set, and so on.
Edit: Something like this:
template<typename T>
class TProxy
{
T m_value;
public:
TProxy(T i_t) : m_value(i_t) {};
template<typename T>
TProxy(const TProxy<T> &i_rhs) : m_value(i_rhs.m_value) {}
T get() { return m_value; }
void set(T i_t) { m_value = i_t; }
};
template<typename T>
class TProxy<const T *>
{
const T *mp_value;
public:
TProxy(const T *ip_t) : mp_value(ip_t) {};
template<typename T>
TProxy(const TProxy<T> &i_rhs) : m_value(i_rhs.mp_value) {}
T get() { return m_value; }
};
Why not replace float* with float in A. If you don't either the original owner of the float that the float* references can change it, or anyone prepared to do a mutable cast on the return value from a::get.
const is always just a hint to the compiler; there are no ways to make a variable permanently read-only.
I think you should use deep copy and define your own assingment operator and copy constructor.
Also to return handle to internal data structure in not a good practice.
You can deny the copy-constructor for certain combinations of arguments:
For instance, adding the constructor;
A(A& a) :m_pt(a.m_pt) { m_pt = a.m_pt; }
prevents any instance of A being initialised with a const A.
This also prevents const A a2 = a1 where a1 is const, but you should never need to do this anyway, since you can just use a1 directly - it's const even if you could make a copy, a2 would be forever identical to a1.