How to understand this expression in C++ struct? - c++

struct Task{
int value,time,deadline;
bool operator < (const Task& t1)const{
return d<t1.deadline;
}
}task[1000];
I've read this block of code of struct initialization.
the first line, initialize variables, is easy to grasp.
What about the second line? the bool operator thing. Seems like some kind of sorting rules. I have never seen any code like this in cpp before, could someone help me to understand it?

What you observe is called operator overloading. In this case the operator< is overloaded for class Task.
This is done in order to be able to write something like this.
Task t1{1,2,3};
Task t2{2,3,4};
if(t1 < t2) //note, the operator< is called
{
//do your thing
}

To add to the answer, I would like to point out that the variables are not initialized (in traditional sense). It is so called default initialization or, rather, a lack of initialization as the variables will be of whatever value that happened to be in the memory at that time.
To zero-initialize the array, you'll need to use the following syntax (that resembles calling a default constructor of an array)
struct Task{
int value, time, deadline;
bool operator < (const Task& t1) const {
return deadline < t1.deadline;
}
} task[1000]{};
...Well, it's simple in your case, since you don't have any user-declared constructors, but in other cases it may become tricky. Read this if you're interested value-initialization.
(And {} is a new syntax for constructing objects introduced in C++11. The prior syntax () has several issues: it does not check that arguments are narrowed, and it suffers from the most vexing parse problem, when Foo aVariable(std::string("bar")); is parsed as function declaration (see).)

Related

Emulate copy-assignment operator for lambdas in C++

This question has two parts
Firstly, can someone explain the rationale behind C++ disabling the copy-assignment operator for lambdas? If you're going to allow the copy constructor, why not the copy-assignment operator?
Secondly, how do you best overcome this limitation without forcing people to write C++03 style functors, or using std::function (the functions I'm dealing with are tiny, and I'd like the compiler to inline them wherever possible)?
Background:
I'm trying to implement a flat_map like operation in a stream processing library I'm writing, similar to flatMap in Scala or other functional languages. As a result, I need to create an iterator that iterates over a list of iterators. Each time the flat_map iterator is de-referenced a lambda associated with the inner iterator is executed. The outer iterator needs to switch the inner iterator each time the inner iterator reaches the end. Since the inner iterator contains a lambda, and therefore does not have a copy-assignment operator, it's not possible to switch it. Technically I could solve the problem using dynamic allocation, so that I always call the copy-constructor, but that doesn't seem like the right approach. Here is a snippet of code that might help highlight the problem:
template <typename Iter>
class flat_map_iterator {
public:
flat_map_iterator& operator++() {
++it_inner_;
if (it_inner_ == (*it_outer_).end()) {
++it_outer_;
// ERROR: cannot be assigned because its copy assignment operator is implicitly deleted
it_inner_ = (*it_outer_).begin();
}
return *this;
}
private:
Iter it_outer_;
typename Iter::value_type::iterator it_inner_;
};
Edit:
Thanks for the really quick responses. Here is a use case example:
int res = ftl::range(1, 4).map([](int a){
return ftl::range(a, 4).map([a](int b){
return std::make_tuple(a, b);
});
})
.flat_map([](std::tuple<int, int> x){ return std::get<0>(x) * std::get<1>(x); })
.sum();
assert(res, 25);
The ftl::range(begin, end) function returns a lazy iterator over the range [begin, end).
It's not that C++ disables the copy-assignment operator for lambda per-se, but that by default members in a lambda object are saved as const, and then the assignment operator can basically do nothing to assign to them, and so it is not generated. If you want lambdas to not hold members as const, you use the [...](...) mutable {...} syntax.
The other thing is that I'm not entirely sure what you get out of assigning lambdas. I mean, if you're going to re-use the lambda type (and functionality) and simply bind it to different variables, you're already working against the nice lambda capture syntax, and might as well have it be a normal function object. Assigning one type of lambda to another one is impossible. This means that you can not provide different lambda implementations when you hold the lambda itself by value.
If this is still what you're going for, I think dynamic allocation (e.g. using unique_ptr) is fair game.
And if you really want to avoid it, you could manually destruct and re-construct your lambda, as the following example illustrates:
#include <iostream>
template <class T>
struct LambdaContainer {
LambdaContainer(const T& lambda)
: lambda{lambda} {}
void resetLambda(const T& lambda) {
this->lambda.~T();
new (&this->lambda) T{lambda};
}
T lambda;
};
int main()
{
int i = 1;
auto l = [=]() {
std::cout << i;
};
using LT = decltype(l);
LambdaContainer<LT> lc{l};
lc.resetLambda(l);
}

Copy constructors with move-only, but cloneable types in member containers

Assume that we have two types, T1 and T2.
T1 isn't important except the following facts:
it isn't copy constructible
it has a move constructor
we have an excellent function with the signature T1 copy(T1 const& orig), which creates a copy.
T2 can be simplified to the following class:
// T2.h
class T2 {
public:
T2() { /* initializes the vector with something */ }
T2(T2 const& other);
private:
std::vector<T1> v;
}
// T2.cpp
T2::T2(T2 const& other) : ... {}
How would you implement this method, if you could only write to the ellipsis part, or to the global scope?
A simple real world use case - assuming the "you can't write anything between the curly braces" part is a real world restriction:
T1 is std::unique_ptr<anything>
copy is std::make_unique
anything has a copy constructor
I also have two additional requirements for the implementation:
performance. It shouldn't be (considerably) slower than the naive implementation with a for loop in the copy constructor's body.
readability. The entire point behind the question is to do something which is more clear/clean than the trivial for loop (e.g. imagine T2 with two or more member vectors).
And optional, but nice to have features:
something that's easily generalized to other containers
something that works with just iterators
something that's generic
A clarification: I know the question is trivially solvable with a std::vector<T1> copy_vec(std::vector<T1> const& orig) global function. Placing that function into an anonymous namespace within T2.cpp would also make it local, but I would argue against its readability, I think it wouldn't be better than the for loop at all. And it's clearly a bad solution if the copy constructor isn't in an implementation file but inlined in the header.
So a rephrasing of my question is:
Is there already something similar implemented, which I can just include?
If there is none, then why? I'm not saying I thought about every corner case, but I think this is something that possibly can be implemented in a nice generic way, and thanks to unique_ptr, it's a common enough case.
Nothing wrong with a naive loop:
v.reserve(other.v.size());
for (auto& elem : other.v) {
v.push_back(copy(elem));
}
That's plenty readable and optimal.
Though I guess the modern, clever solution with be to use range-v3:
T2(T2 const& other)
: v(other.v | view::transform(copy))
{ }
I'm not sure that's enough better than the loop to justify the additional complexity but YMMV.

Overloading operator [] for both read and write

I'm having a trouble overloading operator [] for both read and write in my objects. This is a large code with different components and I'm not going to put all the details here since it wont help. In a nutshell what I have is the following
class MyObject(){
inline SetterProxy& operator[](int i) {
SetterProxy a(i);
return a;
}
inline double operator[](int i) const{
return some_value;
}
}
The first overloaded [] works fine for assigning values (if you are wondering what the SetterProxy is, I have to use Proxy classes to be able to do some checking and internal function calls before assigning values). However, the second one which should supposedly be called when reading does not work and the code crashes. I'm not sure what is happening here but when I comment out the first one it just works fine! Could it be that compiler somehow confuses the two since they are both inline?
Any thought would be appreciated.
EDIT:
Ok here is the SetterProxy itself:
class SetterProxy{
private:
Vec v;
int i;
double *ptr_val;
public:
inline SetterProxy(Vec v_, int i_) {
v = v_;
i = i_;
VecGetArray(v,&ptr_val);
}
inline ~SetterProxy(){
VecRestoreArray(v,&ptr_val);
}
inline void operator=(double rhs ){
ptr_val[i] = rhs;
}
};
Although I dont think its coming directly from that. Also initially I had it to return by value and I though changing it to reference would be more efficient. I think this should be safe since the assignment is done in the Proxy operator=() class and after that the proxy class goes out of scope. Either way, that does not save my problem!
You're returning a reference to a local variable - it goes out of scope when the operator returns, leaving your reference dangling. A good compiler should warn you about this if you turn the warning setting up to a reasonable level.
As noted in #Stuart Golodetz's answer, you are returning a reference to SetterProxy referring to a, which is local to your method and thus goes out of scope when it returns.
You should instead return a SetterProxy instance by value: that shouldn't be a big deal, SetterProxy will probably just hold the index and a reference to the "parent" object, so the compiler-generated copy constructor for it will be fine and the copy won't be costly at all.
By the way, unless you want to allow negative indexes, the usual idiom is to use size_t for indexes in arrays.

C++ vectors, sorting and custom class operators

I am puzzled because I cannot figure where my bug/problem is.
I have a class Instruction, which uses two custom operators, one assignment and one comparison operator.
Previously I only used the comparison operator in order to use std::sort to sort Instructions based on one of their members, an std::string name.
However, since I started re-factoring the entire project, I changed some members to constant. This lead me to having to use an initialization list for those constants.
This in turn, lead me to have to create an assignment operator, because those instructions are being copied when pushed back in vectors.
This is where everything goes wrong.
I include my Class declaration and Constructor and Operators.
instruction.hpp
class Instruction
{
private:
unsigned int param_size;
const float max_angle, min_angle;
bool micro_mutated;
protected:
const std::string body_part;
std::vector<Parameter <float> > parameters;
public:
Instruction(std::string name, float max, float min);
Instruction operator=(const Instruction& I);
bool operator<(const Instruction& I) const;
//there are a few more functions but are completely irrelevant
}
instruction.cpp:
Instruction::Instruction(std::string name,float max, float min) :
body_part (name), max_angle(max), min_angle(min)
{}
Instruction Instruction::operator=(const Instruction& I)
{
(*this) = I;
return (*this);
}
bool Instruction::operator<(const Instruction& I) const
{
return body_part < I.body_part;
}
The only reason why I created an assignment operator (which to be honest I've never done before) was because when I was trying to push_back Instructions, compiler complained about not being able to instantiate "from here" Instructions and I thought it had to do with the constant members. Without the members being constant, everything worked fine, even the sorting.
Now the weird part. If I remove the std::sort, the above code works, but not all the time. Some times it crashed after a while, some times it won't crash. But the moment I include the sorting, it crashes straight away.
Can someone please help ?
Don't forget the rule of threes: if you have one of a copy construct, copy assignment operator, and destructor, then you should have all of them.
However, your copy assignment operator is effectively an infinite loop; it calls itself. Operator= will be used whenever you have anything of the form: Instruction &=Instruction&. Which is exactly what (*this) = I is.
My question is this: why are those things constant? Having members be constant effectively means that you cannot copy the object (unless you use a const-cast) with copy assignment. You can copy construct them, but that's about it.
Is there some reason for those members to be constant? And if so, then you shouldn't be copying these objects by assignment. The two are mutually exclusive.
If you need a member to be effectively constant, unchangable by outside activity (but not language-const which prevents copying), then this should be done with proper accessor methods. Provide users of the class with ways to get these values, but not ways to set them.

Why don't C++ compilers define operator== and operator!=?

I am a big fan of letting the compiler do as much work for you as possible. When writing a simple class the compiler can give you the following for 'free':
A default (empty) constructor
A copy constructor
A destructor
An assignment operator (operator=)
But it cannot seem to give you any comparison operators - such as operator== or operator!=. For example:
class foo
{
public:
std::string str_;
int n_;
};
foo f1; // Works
foo f2(f1); // Works
foo f3;
f3 = f2; // Works
if (f3 == f2) // Fails
{ }
if (f3 != f2) // Fails
{ }
Is there a good reason for this? Why would performing a member-by-member comparison be a problem? Obviously if the class allocates memory then you'd want to be careful, but for a simple class surely the compiler could do this for you?
The argument that if the compiler can provide a default copy constructor, it should be able to provide a similar default operator==() makes a certain amount of sense. I think that the reason for the decision not to provide a compiler-generated default for this operator can be guessed by what Stroustrup said about the default copy constructor in "The Design and Evolution of C++" (Section 11.4.1 - Control of Copying):
I personally consider it unfortunate
that copy operations are defined by
default and I prohibit copying of
objects of many of my classes.
However, C++ inherited its default
assignment and copy constructors from
C, and they are frequently used.
So instead of "why doesn't C++ have a default operator==()?", the question should have been "why does C++ have a default assignment and copy constructor?", with the answer being those items were included reluctantly by Stroustrup for backwards compatibility with C (probably the cause of most of C++'s warts, but also probably the primary reason for C++'s popularity).
For my own purposes, in my IDE the snippet I use for new classes contains declarations for a private assignment operator and copy constructor so that when I gen up a new class I get no default assignment and copy operations - I have to explicitly remove the declaration of those operations from the private: section if I want the compiler to be able to generate them for me.
Even in C++20, the compiler still won't implicitly generate operator== for you
struct foo
{
std::string str;
int n;
};
assert(foo{"Anton", 1} == foo{"Anton", 1}); // ill-formed
But you will gain the ability to explicitly default == since C++20:
struct foo
{
std::string str;
int n;
// either member form
bool operator==(foo const&) const = default;
// ... or friend form
friend bool operator==(foo const&, foo const&) = default;
};
Defaulting == does member-wise == (in the same way that the default copy constructor does member-wise copy construction). The new rules also provide the expected relationship between == and !=. For instance, with the declaration above, I can write both:
assert(foo{"Anton", 1} == foo{"Anton", 1}); // ok!
assert(foo{"Anton", 1} != foo{"Anton", 2}); // ok!
This specific feature (defaulting operator== and symmetry between == and !=) comes from one proposal that was part of the broader language feature that is operator<=>.
The compiler wouldn't know whether you wanted a pointer comparison or a deep (internal) comparison.
It's safer to just not implement it and let the programmer do that themselves. Then they can make all the assumptions they like.
IMHO, there is no "good" reason. The reason there are so many people that agree with this design decision is because they did not learn to master the power of value-based semantics. People need to write a lot of custom copy constructor, comparison operators and destructors because they use raw pointers in their implementation.
When using appropriate smart pointers (like std::shared_ptr), the default copy constructor is usually fine and the obvious implementation of the hypothetical default comparison operator would be as fine.
It's answered C++ didn't do == because C didn't, and here is why C provides only default = but no == at first place.
C wanted to keep it simple:
C implemented = by memcpy; however, == cannot be implemented by memcmp due to padding.
Because padding is not initialized, memcmp says they are different even though they are the same.
The same problem exists for empty class: memcmp says they are different because size of empty classes are not zero.
It can be seen from above that implementing == is more complicated than implementing = in C.
Some code example regarding this.
Your correction is appreciated if I'm wrong.
In this video Alex Stepanov, the creator of STL addresses this very question at about 13:00. To summarize, having watched the evolution of C++ he argues that:
It's unfortunate that == and != are not implicitly declared (and Bjarne agrees with him). A correct language should have those things ready for you (he goes further on to suggest you should not be able to define a != that breaks the semantics of ==)
The reason this is the case has its roots (as many of C++ problems) in C. There, the assignment operator is implicitly defined with bit by bit assignment but that wouldn't work for ==. A more detailed explanation can be found in this article from Bjarne Stroustrup.
In the follow up question Why then wasn't a member by member comparison used he says an amazing thing : C was kind of a homegrown language and the guy implementing these stuff for Ritchie told him he found this to be hard to implement!
He then says that in the (distant) future == and != will be implicitly generated.
C++20 provides a way to easily implement a default comparison operator.
Example from cppreference.com:
class Point {
int x;
int y;
public:
auto operator<=>(const Point&) const = default;
// ... non-comparison functions ...
};
// compiler implicitly declares operator== and all four relational operators work
Point pt1, pt2;
if (pt1 == pt2) { /*...*/ } // ok, calls implicit Point::operator==
std::set<Point> s; // ok
s.insert(pt1); // ok
if (pt1 <= pt2) { /*...*/ } // ok, makes only a single call to Point::operator<=>
It is not possible to define default ==, but you can define default != via == which you usually should define yourselves.
For this you should do following things:
#include <utility>
using namespace std::rel_ops;
...
class FooClass
{
public:
bool operator== (const FooClass& other) const {
// ...
}
};
You can see http://www.cplusplus.com/reference/std/utility/rel_ops/ for details.
In addition if you define operator< , operators for <=, >, >= can be deduced from it when using std::rel_ops.
But you should be careful when you use std::rel_ops because comparison operators can be deduced for the types you are not expected for.
More preferred way to deduce related operator from basic one is to use boost::operators.
The approach used in boost is better because it define the usage of operator for the class you only want, not for all classes in scope.
You can also generate "+" from "+=", - from "-=", etc... (see full list here)
C++0x has had a proposal for default functions, so you could say default operator==;
We've learnt that it helps to make these things explicit.
Conceptually it is not easy to define equality. Even for POD data, one could argue that even if the fields are the same, but it is a different object (at a different address) it is not necessarily equal. This actually depends on the usage of the operator. Unfortunately your compiler is not psychic and cannot infer that.
Besides this, default functions are excellent ways to shoot oneself in the foot. The defaults you describe are basically there to keep compatibility with POD structs. They do however cause more than enough havoc with developers forgetting about them, or the semantics of the default implementations.
Just so that the answers to this question remains complete as the time passes by: since C++20 it can be automatically generated with command auto operator<=>(const foo&) const = default;
It will generate all the operators: ==, !=, <, <=, >, and >=, see https://en.cppreference.com/w/cpp/language/default_comparisons for details.
Due to operator's look <=>, it is called a spaceship operator. Also see Why do we need the spaceship <=> operator in C++?.
EDIT: also in C++11 a pretty neat substitute for that is available with std::tie see https://en.cppreference.com/w/cpp/utility/tuple/tie for a complete code example with bool operator<(…). The interesting part, changed to work with == is:
#include <tuple>
struct S {
………
bool operator==(const S& rhs) const
{
// compares n to rhs.n,
// then s to rhs.s,
// then d to rhs.d
return std::tie(n, s, d) == std::tie(rhs.n, rhs.s, rhs.d);
}
};
std::tie works with all comparison operators, and is completely optimized away by the compiler.
Is there a good reason for this? Why would performing a member-by-member comparison be a problem?
It may not be a problem functionally, but in terms of performance, default member-by-member comparison is liable to be more sub-optimal than default member-by-member assignment/copying. Unlike order of assignment, order of comparison impacts performance because the first unequal member implies the rest can be skipped. So if there are some members that are usually equal you want to compare them last, and the compiler doesn't know which members are more likely to be equal.
Consider this example, where verboseDescription is a long string selected from a relatively small set of possible weather descriptions.
class LocalWeatherRecord {
std::string verboseDescription;
std::tm date;
bool operator==(const LocalWeatherRecord& other){
return date==other.date
&& verboseDescription==other.verboseDescription;
// The above makes a lot more sense than
// return verboseDescription==other.verboseDescription
// && date==other.date;
// because some verboseDescriptions are liable to be same/similar
}
}
(Of course the compiler would be entitled to disregard the order of comparisons if it recognizes that they have no side-effects, but presumably it would still take its que from the source code where it doesn't have better information of its own.)
I agree, for POD type classes then the compiler could do it for you. However what you might consider simple the compiler might get wrong. So it is better to let the programmer do it.
I did have a POD case once where two of the fields were unique - so a comparison would never be considered true. However the comparison I needed only ever compared on the payload - something the compiler would never understand or could ever figure out on it's own.
Besides - they don't take long to write do they?!