maybe I get something wrong with shared_pointers or there is some basic shortcoming of mine but I couldn't get this right. So I want to read in some data from a file. There are position and momentum data on each line of the data file and the first line stores the number of data points.
I need to read this in to my data structure and for some reason my graph would not fill, although the data reads in correctly.
const int dim = 3; // dimension of problem
template <typename T, typename G>
// T is the type of the inputted locations and G is the type of the
// distance between them
// for example: int point with float/double distance
struct Node{
std::pair< std::array<T, dim>,std::pair< std::array<T, dim>, G > > pos; // position
std::pair< std::array<T, dim>,std::pair< std::array<T, dim>, G > > mom; // momentum
// a pair indexed by a position in space and has a pair of position
// and the distance between these points
};
template <typename T, typename G>
struct Graph{
int numOfNodes;
std::vector< Node<T,G> > nodes;
};
This is the data structure and here's my read function (std::cout-s are only for testing):
template <typename T, typename G>
std::istream& operator>>(std::istream& is, std::shared_ptr< Graph<T,G> >& graph){
is >> graph->numOfNodes; // there's the number of nodes on the first line of the data file
std::cout << graph->numOfNodes << "\n";
for(int k=0; k<graph->numOfNodes; k++){
Node<T,G> temp;
for(auto i : temp.pos.first){
is >> i;
std::cout << i << "\t";
}
std::cout << "\t";
for(auto i : temp.mom.first){
is >> i;
std::cout << i << "\t";
}
std::cout << "\n";
graph->nodes.push_back(temp);
}
return is;
}
I have an output function as well. So if I output the graph which I intended to fill during read-in is zeroed out. Number of nodes os correct however positions and momente are all zeroed out. What did I do wrong? Thanks in advance.
for(auto i : temp.pos.first){
is >> i;
std::cout << i << "\t";
}
Think of this as similar to a function. If you have something like:
void doX(int i) { i = 42; }
int main() {
int j=5;
doX(j);
return j;
}
Running this code, you'll see the program returns the value 5. This is because the function doX takes i by value; it basically takes a copy of the variable.
If you replace doX's signature with
void doX(int &i)
and run the code, you'll see it returns 42. This is because the function is now taking the argument by reference, and so can modify it.
Your loops will behave similarly. As you have it now, they take a copy of the values in the arrays in turn, but are not by reference.
As with the function, you can change your loops to look like
for(auto &i : temp.pos.first){
is >> i;
std::cout << i << "\t";
}
This should then let you change the values stored in the arrays.
Related
I'm implementing an algorithm to return a vector string array with only the largest elements in the vector string array of entrance:
vector<string> solution(vector<string> inputArray) {
vector<string> s;
auto m = *max_element(inputArray.begin(),inputArray.end());
for(int i=0;i<inputArray.size();i++){
if(inputArray[i].size() == m.size())
{
s.push_back(inputArray[i]);
}
}
return s;
It works for every test case except in the case the entry string vector is {"enyky", "benyky","yely","varennyky"}. 'm' should return a pointer to "varennyky", but it returns a pointer to "yely" instead.
I digged in to the documentation for max_element, but cant find what I'm doing wrong. Can anybody help me?
Your function is comparing the strings lexicographically, which is the default comparison in case of strings.
To illustrate, consider the following example:
#include <algorithm>
#include <string>
#include <vector>
// Print a vector of strings
void print_vec(std::vector<std::string> vec)
{
for (const auto& el : vec) {
std::cout << el << " ";
}
std::cout << std::endl;
}
// Compares strings by length
bool less_length(const std::string& s1, const std::string& s2)
{
return s1.length() < s2.length();
}
int main()
{
std::vector<std::string> test_0 = {"enyky", "benyky","yely","varennyky"};
// Default sort and max element
std::sort(test_0.begin(), test_0.end());
print_vec(test_0);
const auto largest_0 = *std::max_element(test_0.begin(), test_0.end());
std::cout << "Largest member (lexicographically): " << largest_0 << '\n' << std::endl;
// Sort and max element by string size
std::sort(test_0.begin(), test_0.end(), less_length);
print_vec(test_0);
const auto largest_1 = *std::max_element(test_0.begin(), test_0.end(), less_length);
std::cout << "Largest member (by string length): " << largest_1 << std::endl;
}
The first part of the program runs what you are doing in your function: it finds the maximum element based on lexicographic ordering. According to that ordering, the largest string is yely, you can see that by the output from sort.
The second part uses a custom comparison function, borrowed directly from this book. It uses string length to determine the order in the max_element call and the result is what you were looking for. Again, the sorted vector is also printed for clarity.
#include <memory> // for std::unique_ptr and std::make_unique
#include <iostream>
class Fraction
{
private:
int m_numerator;
int m_denominator;
public:
Fraction(int numerator, int denominator) :
m_numerator{ numerator }, m_denominator{ denominator }
{
}
friend std::ostream& operator<<(std::ostream& out, const Fraction &f1)
{
out << f1.m_numerator << "/" << f1.m_denominator;
return out;
}
friend operator=(const Fraction &f1,const int numerator,const int denominator){
f1.m_numerator=numerator;
f1.m_denominator=denominator;
}
};
int main()
{
// Create a single dynamically allocated Fraction with numerator 3 and denominator 5
std::unique_ptr<Fraction> f1{ std::make_unique<Fraction>(3, 5) };
std::cout << *f1 << '\n';
// Create a dynamically allocated array of Fractions of length 4
// We can also use automatic type deduction to good effect here
auto f2{ std::make_unique<Fraction[]>(4) };
f2[0]=(3,5);
f2[1]=(67,82,5,543345);
std::cout << f2[0] << '\n';
std::cout << f2[1] << '\n';
return 0;
}
First, operator= can be implemented only as member function, not free function. So your approach is just wrong. Second, overloaded operator= can accept only one parameter. The closest thing you want, can be achived by passing initializer_list as this parameter:
Fraction& operator=(std::initializer_list<int> il){
// some code validating size of il here
this->m_numerator=*il.begin();
this->m_denominator = *(il.begin()+1);
return *this;
}
the use looks like:
f2[0]={3,5};
f2[1]={67,84};
Full demo
I made a simple example to test boost bind's interaction with derived classes.
I created two subclasses with different getarea functions. I expected
g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec)
to print the area of Rectangle(10,20) but instead it printed '1'. I get the same when I instead write Rectangle::getarea. It prints the same even when I input other functions eg. member of Rectangle
double sum(double h,double w){return h+w; }
and use
g1 = boost::bind(boost::mem_fn(&Rectangle::sum), Rec,2,3)
Question 1: Why does it return '1'?Is that a default response for error?
My second problem is to do the same of printing g2 but now Rec is replaced by **iter, i.e. an object of some derived class type from a list of objects. Since getarea is a virtual fcn, once I get the above working it should be fine to just write:
g2= boost::bind(boost::mem_fn(& Shape::getarea , &(**iter));
Question 2: However, I was wondering if there is a way to return the classtype of **iter eg. classof(**iter) and then put it in g2 i.e.
g2= boost::bind(boost::mem_fn(& classof(**iter)::getarea , &(**iter));
When I ran g2 by writing Shape::getarea, I got '1' again for all iter.
#include <memory>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <boost/bind.hpp>
using namespace std;
class Shape {
public:
Shape(double h, double w) :height(h), width(w) {};
virtual double getarea() = 0;
double height;
double width; };
class Rectangle: public Shape {
public:
Rectangle(double h, double w): Shape(h,w) {};
double getarea() override { return height*width; } };
class Triangle : public Shape {
public:
Triangle(double h, double w) :Shape(h,w) {};
double getarea() { return height*width*0.5; }};
int main() {
//create objects
Rectangle Rec(10, 20);
Triangle Tri(2, 3);
//create boost bind function
boost::function<double(double, double)> g1;
g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec);
//print area and g
cout << Rec.getarea()<<" should be equal to " << g1<< '\n';
//create list
vector<shared_ptr<Shape>> Plist;
Plist.push_back(make_shared<Rectangle>(Rec));
Plist.push_back(make_shared<Triangle>(Tri));
//print each element from the vector list
for (auto iter = Plist.begin(); iter != Plist.end(); iter ++ ) {
boost::function<double(double, double)> g2;
g2= boost::bind(boost::mem_fn(& .... , &(**iter));
//where in dots we need Classtype_of_**iter::getarea
cout << (**iter).getarea()<<"should be equal to " << g2<< '\n';
}
}
You... forget to invoke the functions...
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
boost::function<double()> g2;
g2 = boost::bind(&Shape::getarea, iter->get());
cout << (*iter)->getarea() << " should be equal to " << g2() << '\n';
}
What you saw what the implicit conversion to bool (http://www.boost.org/doc/libs/1_60_0/doc/html/boost/function.html#idm45507164686720-bb)
Note also I fixed the signature of g1 and g2: Live On Coliru.
Some further improvements (remove the need for the g2 in the loop?):
auto getarea = boost::mem_fn(&Shape::getarea);
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
cout << (*iter)->getarea() << " should be equal to " << getarea(**iter) << '\n';
}
Or, indeed in c++11:
for (auto& s : Plist)
cout << s->getarea() << " should be equal to " << getarea(*s) << '\n';
By this time, you'd wonder why you have this accessor when you can just use the member.
In some data structures, it would be useful to have members whose values are computed from the other data members upon access instead of stored.
For example, a typical rect class might store it's left, top, right and bottom coordinates in member data fields, and provide getter methods that return the computed width and height based on those values, for clients which require the relative dimensions instead of the absolute positions.
struct rect
{
int left, top, right, bottom;
// ...
int get_width() const { return right - left; }
int get_height() const { return bottom - top; }
};
This implementation allows us to get and set the absolute coordinates of the rectangles sides,
float center_y = (float)(box.top + box.bottom) / 2.0;
and additionally to get it's relative dimensions, albeit using the slightly different method-call operator expression syntax:
float aspect = (float)box.get_width() / (float)box.get_height();
The Problem
One could argue, however, that it is equally valid to store the relative width and height instead of absolute right and bottom coordinates, and require clients that need to compute the right and bottom values to use getter methods.
My Solution
In order to avoid the need to remember which case requires method call vs. data member access operator syntax, I have come up with some code that works in the current stable gcc and clang compilers. Here is a fully functional example implementation of a rect data structure:
#include <iostream>
struct rect
{
union {
struct {
union { int l; int left; };
union { int t; int top; };
union { int r; int right; };
union { int b; int bot; int bottom; };
};
struct {
operator int() {
return ((rect*)this)->r - ((rect*)this)->l;
}
} w, width;
struct {
operator int() {
return ((rect*)this)->b - ((rect*)this)->t;
}
} h, height;
};
rect(): l(0), t(0), r(0), b(0) {}
rect(int _w, int _h): l(0), t(0), r(_w), b(_h) {}
rect(int _l, int _t, int _r, int _b): l(_l), t(_t), r(_r), b(_b) {}
template<class OStream> friend OStream& operator<<(OStream& out, const rect& ref)
{
return out << "rect(left=" << ref.l << ", top=" << ref.t << ", right=" << ref.r << ", bottom=" << ref.b << ")";
}
};
/// #brief Small test program showing that rect.w and rect.h behave like data members
int main()
{
rect t(3, 5, 103, 30);
std::cout << "sizeof(rect) is " << sizeof(rect) << std::endl;
std::cout << "t is " << t << std::endl;
std::cout << "t.w is " << t.w << std::endl;
std::cout << "t.h is " << t.h << std::endl;
return 0;
}
Is there anything wrong with what I am doing here?
Something about the pointer-casts in the nested empty struct types' implicit conversion operators, i.e. these lines:
return ((rect*)this)->r - ((rect*)this)->l;
feels dirty, as though I may be violating good C++ style convention. If this or some other aspect of my solution is wrong, I'd like to know what the reasoning is, and ultimately, if this is bad practice then is there a valid way to achieve the same results.
One thing that I would normally expect to work doesn't:
auto w = t.w;
Also, one of the following lines works, the other does not:
t.l += 3;
t.w += 3; // compile error
Thus, you have not changed the fact that users need to know which members are data and which are functions.
I'd just make all of them functions. It is better encapsulation anyway. And I would prefer the full names, i.e. left, top, bottom, right, width and length. It might be a few more characters to write, but most code is read much more often than it is written. The extra few characters will pay off.
How to execute the body of the loop for every member of some type? I know I could repeat the body of the loop for the maxval after the loop, but it would be duplicating code which is bad. I also could make a function out of the body but it looks wrong to me too because functions should be small and simple and the body of the loop is huge.
const auto minval = std::numeric_limits<T>::min();
const auto maxval = std::numeric_limits<T>::max();
for (auto i = minval; i < maxval; ++i) {
// huge body of the loop
}
It is as simple as stopping after you process the last item:
auto i = minval;
while(1) {
// do all the work for `i`
if (i == maxval) break;
++i;
}
One can also move the increment to the top of the loop, provided it is skipped on the first pass:
i = minval;
switch (1) {
case 0:
do {
++i;
case 1:
// processing for `i`
} while (i != maxval);
}
The latter version translates to efficient machine code a little more directly, as each loop iteration has only a single conditional branch, and there is a single unconditional branch, while in the first there is a conditional branch plus an unconditional branch which both repeat every iteration.
Neither version increments the ultimate value, which might be undefined behavior.
You have to maintain a bit of additional state to indicate whether you've seen the last value or not. Here's a simple example that could be moved to a more idiomatic iterator style without too much work:
#include <iostream>
#include <limits>
using namespace std;
template <typename T>
class allvalues
{
public:
allvalues() = default;
T next()
{
if (done) throw std::runtime_error("Attempt to go beyond end of range");
T v = val;
done = v == std::numeric_limits<T>::max();
if (!done) ++val;
return v;
}
bool isDone() { return done; }
private:
T val = std::numeric_limits<T>::min();
bool done = false;
};
int main() {
allvalues<char> range;
while (!range.isDone())
{
std::cout << "Value = " << (int)range.next() << std::endl;
}
allvalues<unsigned char> urange;
while (!urange.isDone())
{
std::cout << "Value = " << (unsigned int)urange.next() << std::endl;
}
std::cout << "That's it!" << std::endl;
}