Line 76 in Huffman.cpp you did this int buffer{}; and than you used static_cast<char>() every time you use it. So why not just make it char buffer{}; from the beginning ? |
where did the get() method come from ? |
how this :std::deque<std::reference_wrapper<node>> NodeData; works. |
reference_wrapper
which basically turns it into pointer to reference, so we can have a container of those. So now we can have reference semantics.the only thing i understood is that a deque is a doubly linked que that is most efficient to insert elements and delete them on request. |
std::deque
is a double ended queue, not a double linked. It is efficient for inserting / removing at the front and back. But there are tradeoffs:what are these includes for ?
|
<memory>
I had that while experimenting with unique_ptr
<functional>
is for std::reference_wrapperThe way you insert new elements into the deque aren't they still raw pointers ? |
push_back
a parent, which is a node and it becomes a reference, as far as I understand it. std::deque<node>
and just use emplace_back
? I will try that :+)
line 76 in Huffman.cpp you did this int buffer{}; and than you used static_cast<char>() every time you use it. So why not just make it char buffer{}; from the beginning ? |
std::deque<node>
, and it is compiling:
|
|
|
|
node
, so we can use emplace_back
in the storeFreqTable
function, this avoiding push_back
which copies.
|
|
|
|
reference_wrapper
be ?This gives this warning: ./Huffman/Huffman.cpp:85:36: warning: conversion to 'char' from 'int' may alter its value [-Wconversion] buffer |= index << (7 - offSet); |
shrink_to_fit()
before returning the front element from the maketree function because it freed the memory used by the vector, shouldn't i do it with a deque aswell before returning the front element?
-Well as far as i can understand it warns me that it can potentially try to modify a 10th bit for example if offset = -3 and it would force a type conversion but as i take care of it with the latter if statement i don't see it happening (as well as a situation like this: 7 - (-3) wouldn't happen as offset will never go negative). |
-Other than that i try to avoid the generic int because it can cause a portability issue between architectures. |
-Another thought i had is should i make the m_code variable a deque<bool> ? as it only does insertion and deletion and should be more efficient in theory than a vector. |
push_back
and pop_back
, so I doubt if it will make any difference. Note there are costs with having a deque. If there was push_front
and pop_front
, then it would be worth it. On the other hand, std::vector<bool>
is a bit of infamous container, one of the alternatives is std::deque<bool>
. But all you are doing is pushing and popping the end, that is, not anything tricky like iterating it for example.-Should i change all of the uint64_t declarations to std::size_t ? (note that the concern is portability to other architectures) |
std::size_t
is usually the largest unsigned integer type the system has, so for 64 bit it is the same as uint64_t
This is still the case on 32 bit, unsigned long long
is still 64 bit. So I guess it's a moot point.-In my code i used shrink_to_fit() before returning the front element from the maketree function because it freed the memory used by the vector, shouldn't i do it with a deque aswell before returning the front element? |
std::priority_queue
. It probably does the same thing as your code, but anything in the STL is likely to be better in some way.Does it? I don't know, maybe someone else can comment on how to do these things in an independent way. I would have thought that a program that works on one system would work the same on another system. By that I mean normal C++ expressions, not for anything written specifically for a particular OS. |
-Should i change all of the uint64_t declarations to std::size_t ? (note that the concern is portability to other architectures) |
|
|
It compiles but crashes as soon as i run it. |
compress
function:m_root = makeTree();
makeTree
returns a reference, but you have:*m_root = makeTree();
#include <ctime>
, not ctime.hm_root = makeTree();
wont even compile it tells that there is no suitable conversion from node to node* even though we return a reference...Another thing: #include <ctime> , not ctime.h |
Well for me m_root = makeTree(); wont even compile |
|
|
didn't make any problems for me atleast. |
Btw i am working on a copy of the code that uses dynamic allocations for nodes and all seems to work (finally made a destructor). |
What do you mean by dynamic allocations? |
new
and delete
|
|
If you set up version control using git say, you could create separate branches for your own, and my code. One can get it track different versions of both of them, and show differences between them. |
Where you have a pointer there :+) May not be a problem either way. |
node
still doesn't work.buffer |= index << (7 - offSet);
char
doesn't give any warnings for me now.I mean using new and delete |
I have updated the code above to use node still doesn't work. |
i have made both offSet and buffer char doesn't give any warnings for me now. |
int
, no warnings. However, I tried to have char seven = 7;
and buffer |= index << (seven - offSet);
along with buffer and index being char. I thought this might be an improvement because we have removed the int
that comes from the literal 7 we had before. But I still get a -Wconversion warning there. Anyway, the way I have it there are no warnings :+) The other thing to remember is that we are using different compilers, the respective set set of warnings we have enabled may not be the same. If one compiler A gives a warning and the other B doesn't - that means the warning is somehow not enabled or has different behaviour on compiler B. Btw i decided to keep the vector<bool> inside of the encode function because the performance there would be similar to a deque with a big differance in the memory allocated, in other words a deque takes more memory per object than a vector. |
vector<bool>
I have a vague idea about vector<bool> storing each bool as a single byte, this was to get around the problems of vector<bool> not satisfying all the requirements for a container. I might be wrong, maybe someone else can comment on that? Another alternative is boost dynamic bitset:std::bitset
, but the size has to be known at compile time.I also implemented the new structure of the keys generated and now i want to make them as .bin files because they would take less memory for example: |
TheIdeasMan wrote: |
---|
@others I know this all sounds pedantic, but I for one would like to know why that change above still gives a warning when all the variables are char? Is it because of the subtraction? |
cppreference wrote: |
---|
Numeric promotions Integral promotion prvalues of small integral types (such as char) may be converted to prvalues of larger integral types (such as int). In particular, arithmetic operators do not accept types smaller than int as arguments, and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable. This conversion always preserves the value. |
<<
operator, and |=
, and originally the literal 7
. It's also why I had no warnings when I made the types int
. But it also meant casting back to char
where necessary - so no warnings Happy Days :+) ++ThingsLearnt;
It still does for me -Wconversion |
boost dynamic bitset |
It probably doesn't matter, but my code compiles without pointers there. |
createBinaryFile
, and am confused about why it does what it does - it looks more like encryption. Wouldn't one just write the m_key.second
(The vector<bool>
) to the file? Why apply the buffer = buffer | index << (7 - offSet);
? Even if it was supposed to be encryption, that operation is not reversible given the implicit conversion back to char
type.
|
|
|
|
I have looked at the createBinaryFile, and am confused about why it does what it does - it looks more like encryption. Wouldn't one just write the m_key.second (The vector<bool>) to the file? Why apply the buffer = buffer | index << (7 - offSet); ? Even if it was supposed to be encryption, that operation is not reversible given the implicit conversion back to char type. |
buffer = buffer | index << (7 - offSet);
takes care of this for us.