Objective : Design a priority_queue:
Problem : How to use reference as argument of my constructor.
Current Implementation: [Stub] Will compile if algorithm, vector and functional are included. I do not claim it as mine. I read somewhere as to how it is implemented and then tried re-creating from memory.
template <typename T,class container = std::vector<T>,
class cmp std::less<T> >
class priority_queue{
public:
explicit priority_queue(container c = container(),
cmp x = cmp()):
cx(c),
cm(x)
{
std::make_heap(cx.begin(), cx.end(), cm);
}
private:
container cx;
cmp cm;
This works.
However, the following is what I desire.
priority_queue(container &c = container(),
cmp &x = cmp())
This is to avoid the rvalue getting initialized with as container() and then getting copied to "c" which is later copied to cx.
If I do not specify a default value, everything will work.
Related
Does the "auto" keyword in C++ have anything to do with storage class
For example:
void foo() {
auto ptr = new int[9]
}
Does the pointer to int above have is automatic(stack), or dynamic(heap)?
Until c++11, auto was used to specify automaticstorage duration. But since c++11 its only meaning is that the type of the variable is automatically deduced. It has nothing to do wiith the storage-class of the variable itself.
In your case ptr is a local variable (int * ptr) pointing to a location on the heap. You can always get the same effect by explicitely writing the types of the variables as in the following:
void foo() {
int* ptr = new int[9];
}
Please take a look at this link for more details and on how the deduction process works.
http://en.cppreference.com/w/cpp/language/auto
I'd started a bare-metal (Cortex-M) project some years ago. At project setup we decided to use gcc toolchain with C++11 / C++14 etc. enabled and even for using C++ exceptions and rtti.
We are currently using gcc 4.9 from launchpad.net/gcc-arm-embedded (having some issue which prevent us currently to update to a more recent gcc version).
For example, I'd wrote a base class and a derived class like this (see also running example here):
class OutStream {
public:
explicit OutStream() {}
virtual ~OutStream() {}
OutStream& operator << (const char* s) {
write(s, strlen(s));
return *this;
}
virtual void write(const void* buffer, size_t size) = 0;
};
class FixedMemoryStream: public OutStream {
public:
explicit FixedMemoryStream(void* memBuffer, size_t memBufferSize): memBuffer(memBuffer), memBufferSize(memBufferSize) {}
virtual ~FixedMemoryStream() {}
const void* getBuffer() const { return memBuffer; }
size_t getBufferSize() const { return memBufferSize; }
const char* getText() const { return reinterpret_cast<const char*>(memBuffer); } ///< returns content as zero terminated C-string
size_t getSize() const { return index; } ///< number of bytes really written to the buffer (max = buffersize-1)
bool isOverflow() const { return overflow; }
virtual void write(const void* buffer, size_t size) override { /* ... */ }
private:
void* memBuffer = nullptr; ///< buffer
size_t memBufferSize = 0; ///< buffer size
size_t index = 0; ///< current write index
bool overflow = false; ///< flag if we are overflown
};
So that the customers of my class are now able to use e.g.:
char buffer[10];
FixedMemoryStream ms1(buffer, sizeof(buffer));
ms1 << "Hello World";
Now I'd want to make the usage of the class a bit more comfortable and introduced the following template:
template<size_t bufferSize> class FixedMemoryStreamWithBuffer: public FixedMemoryStream {
public:
explicit FixedMemoryStreamWithBuffer(): FixedMemoryStream(buffer, bufferSize) {}
private:
uint8_t buffer[bufferSize];
};
And from now, my customers can write:
FixedMemoryStreamWithBuffer<10> ms2;
ms2 << "Hello World";
But from now, I'd observed increasing size of my executable binary. It seems that gcc added symbol information for each different template instantiation of FixedMemoryStreamWithBuffer (because we are using rtti for some reason).
Might there be a way to get rid of symbol information only for some specific classes / templates / template instantiations?
It's ok to get a non portable gcc only solution for this.
For some reason we decided to prefer templates instead of preprocessor macros, I want to avoid a preprocessor solution.
First of all, keep in mind that compiler also generates separate v-table (as well as RTTI information) for every FixedMemoryStreamWithBuffer<> type instance, as well as every class in the inheritance chain.
In order to resolve the problem I'd recommend using containment instead of inheritance with some conversion function and/or operator inside:
template<size_t bufferSize>
class FixedMemoryStreamWithBuffer
{
uint8_t buffer[bufferSize];
FixedMemoryStream m_stream;
public:
explicit FixedMemoryStreamWithBuffer() : m_stream(m_buffer, bufferSize) {}
operator FixedMemoryStream&() { return m_stream; }
FixedMemoryStream& toStream() { return m_stream; }
};
Yes, there's a way to bring the necessary symbols almost down to 0: using the standard library. Your OutStream class is a simplified version of std::basic_ostream. Your OutStream::write is really just std::basic_ostream::write and so on. Take a look at it here. Overflow is handled really closely, though, for completeness' sake, it also deals with underflow i.e. the need for data retrieval; you may leave it as undefined (it's virtual too).
Similarly, your FixedMemoryStream is std::basic_streambuf<T> with a fixed-size (a std::array<T>) get/put area.
So, just make your classes inherit from the standard ones and you'll cut off on binary size since you're reusing already declared symbols.
Now, regarding template<size_t bufferSize> class FixedMemoryStreamWithBuffer. This class is very similar to std::array<std::uint8_t, bufferSize> as for the way memory is specified and acquired. You can't optimize much about that: each instantiation is a different type with all what that implies. The compiler cannot "merge" or do anything magic about them: each instantiation must have its own type.
So either fall back on std::vector or have some fixed-size specialized chunks, like 32, 128 etc. and for any values in between would choose the right one; this can be achieved entirely at compile-time, so no runtime cost.
I am trying to put together an efficient C++1x struct that can take advantage efficient std::move/copy construct/and assignment operations. These structs fall into 2 basic categories, POD structs and non-POD structs. I have gotten into the habit of writing these structs using boilerplate code but I'm pretty sure that the compiler can do a better job at this than I can and its quite a bit of typing for each class. My question is what is the minimum I can do to take advantage of the defaulted compiler operations. I know for example that as soon as I define one explicit constructor, that suppresses the automatic generation of the move and assignment operators. Also I would like the non POD structs that do not have superclasses to have a default destructor and those that inherit from base classes to have a defaulted virtual destructor. The rules on how to do these operations efficiently have always been a bit confusing to me.
The original version of the PAGE_DATA struct is follows
using PAGE_DATA = struct page_data {
std::string name;
std::vector<SCRN_TEXT> elements;
std::vector<int> jumpTable;
};
I then added boilerplate code to make this data structure move aware and I also added an explicit constructor (without which I am forced to initialize it with aggregate initialization using braces which does not read particularly well).
using PAGE_DATA = struct page_data {
explicit page_data(const std::string& rName = std::string(),
const std::vector<SCRN_TEXT>& rElements = std::vector<SCRN_TEXT>(),
const std::vector<int>& rJumpTable = std::vector<int>())
: name(rName)
, elements(rElements)
, jumpTable(rJumpTable)
{}
//! Defaulted copy constructor.
page_data(const page_data&) = default;
//! Defaulted move constructor.
page_data(page_data&&) = default;
//! Non-throwing copy-and-swap idiom unified assignment.
page_data& operator=(page_data rhs) {
rhs.swap(*this);
return *this;
}
//! Non-throwing-swap idiom.
void swap(page_data& rhs) noexcept {
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// swap base members
// ...
// swap members here
swap(name, rhs.name);
swap(elements, rhs.elements);
swap(jumpTable, rhs.jumpTable);
}
virtual ~page_data() = default;
std::string name;
std::vector<SCRN_TEXT> elements;
std::vector<int> jumpTable;
};
The dependent simple POD structs that are called out are shown below:
using COLOR_TYPE = enum color_type
{
BLACK = 0x0,
CYAN = 0x1,
RED = 0x2,
YELLOW = 0x3,
GREEN = 0x4,
MAGENTA = 0x5,
AMBER = 0x6,
WHITE = 0x7
};
using SIZE_TYPE = enum size_type {
SMALL_CHAR = 0x0,
BIG_CHAR = 0x1
};
using MODIFY_TYPE = enum modify_type {
NORMAL = 0x0,
UNDER = 0x2,
FLASH = 0x4,
FLASH_UNDER = 0x6
};
using SCREEN_ATTR = struct screen_attr {
COLOR_TYPE color : 4;
SIZE_TYPE size : 2;
MODIFY_TYPE blink : 4;
unsigned char unused : 6;
};
using CDU_ROWCOL = struct cdu_rowcol {
int v;
int h;
};
using SCRN_TEXT = struct scrn_text {
CDU_ROWCOL loc;
SCREEN_ATTR attrib;
std::string text;
};
After putting together a live coliru demo, I was able to verify that the boiler plate does the right thing,.
int main() {
std::cout << "assertions work fine" << std::endl;
static_assert(std::is_copy_constructible<PAGE_DATA>(), "not copy constructible");
static_assert(std::is_move_constructible<PAGE_DATA>(), "not move constructible");
}
Your original structure was already perfectly move constructible. All the extra boilerplate code you wrote is already generated by the compiler when needed.
My question is what is the minimum I can do to take advantage of the defaulted compiler operations.
The minimum - which is quite the optimal amount - is your original version which takes full advantage of the defaulted operations.
Your page_data::swap is probably slightly more efficient than the generic std::swap and it doesn't prevent the generation of any implicit member function so it may be worth to keep in. However, it's probably only marginally better if at all, so you may want to measure whether it is worth cluttering your class definition.
I like this answer to my question, "... if you find yourself writing move operators and move constructors it's because you have not sufficiently decomposed the problem."
I often use the "dependency injection" pattern in my projects. In C++ it is easiest to implement by passing around raw pointers, but now with C++11, everything in high-level code should be doable with smart pointers. But what is the best practice for this case? Performance is not critical, a clean and understandable code matters more to me now.
Let me show a simplified example. We have an algorithm that uses distance calculations inside. We want to be able to replace this calculation with different distance metrics (Euclidean, Manhattan, etc.). Our goal is to be able to say something like:
SomeAlgorithm algorithmWithEuclidean(new EuclideanDistanceCalculator());
SomeAlgorithm algorithmWithManhattan(new ManhattanDistanceCalculator());
but with smart pointers to avoid manual new and delete.
This is a possible implementation with raw pointers:
class DistanceCalculator {
public:
virtual double distance(Point p1, Point p2) = 0;
};
class EuclideanDistanceCalculator {
public:
virtual double distance(Point p1, Point p2) {
return sqrt(...);
}
};
class ManhattanDistanceCalculator {
public:
virtual double distance(Point p1, Point p2) {
return ...;
}
};
class SomeAlgorithm {
DistanceCalculator* distanceCalculator;
public:
SomeAlgorithm(DistanceCalculator* distanceCalculator_)
: distanceCalculator(distanceCalculator_) {}
double calculateComplicated() {
...
double dist = distanceCalculator->distance(p1, p2);
...
}
~SomeAlgorithm(){
delete distanceCalculator;
}
};
Let's assume that copying is not really an issue, and if we didn't need polymorphism we would just pass the DistanceCalculator to the constructor of SomeAlgorithm by value (copying). But since we need to be able to pass in different derived instances (without slicing), the parameter must be either a raw pointer, a reference or a smart pointer.
One solution that comes to mind is to pass it in by reference-to-const and encapsulate it in a std::unique_ptr<DistanceCalculator> member variable. Then the call would be:
SomeAlgorithm algorithmWithEuclidean(EuclideanDistance());
But this stack-allocated temporary object (rvalue-reference?) will be destructed after this line. So we'd need some copying to make it more like a pass-by-value. But since we don't know the runtime type, we cannot construct our copy easily.
We could also use a smart pointer as the constructor parameter. Since there is no issue with ownership (the DistanceCalculator will be owned by SomeAlgorithm) we should use std::unique_ptr. Should I really replace all of such constructor parameters with unique_ptr? it seems to reduce readability. Also the user of SomeAlgorithm must construct it in an awkward way:
SomeAlgorithm algorithmWithEuclidean(std::unique_ptr<DistanceCalculator>(new EuclideanDistance()));
Or should I use the new move semantics (&&, std::move) in some way?
It seems to be a pretty standard problem, there must be some succinct way to implement it.
If I wanted to do this, the first thing I'd do is kill your interface, and instead use this:
SomeAlgorithm(std::function<double(Point,Point)> distanceCalculator_)
type erased invocation object.
I could do a drop-in replacement using your EuclideanDistanceCalculator like this:
std::function<double(Point,Point)> UseEuclidean() {
auto obj = std::make_shared<EuclideanDistance>();
return [obj](Point a, Point b)->double {
return obj->distance( a, b );
};
}
SomeAlgorithm foo( UseEuclidean() );
but as distance calculators rarely require state, we could do away with the object.
With C++1y support, this shortens to:
std::function<double(Point,Point>> UseEuclidean() {
return [obj = std::make_shared<EuclideanDistance>()](Point a, Point b)->double {
return obj->distance( a, b );
};
}
which as it no longer requires a local variable, can be used inline:
SomeAlgorithm foo( [obj = std::make_shared<EuclideanDistance>()](Point a, Point b)->double {
return obj->distance( a, b );
} );
but again, the EuclideanDistance doesn't have any real state, so instead we can just
std::function<double(Point,Point>> EuclideanDistance() {
return [](Point a, Point b)->double {
return sqrt( (b.x-a.x)*(b.x-a.x) + (b.y-a.y)*(b.y*a.y) );
};
}
If we really don't need movement but we do need state, we can write a unique_function< R(Args...) > type that does not support non-move based assignment, and store one of those instead.
The core of this is that the interface DistanceCalculator is noise. The name of the variable is usually enough. std::function< double(Point,Point) > m_DistanceCalculator is clear in what it does. The creator of the type-erasure object std::function handles any lifetime management issues, we just store the function object by value.
If your actual dependency injection is more complicated (say multiple different related callbacks), using an interface isn't bad. If you want to avoid copy requirements, I'd go with this:
struct InterfaceForDependencyStuff {
virtual void method1() = 0;
virtual void method2() = 0;
virtual int method3( double, char ) = 0;
virtual ~InterfaceForDependencyStuff() {}; // optional if you want to do more work later, but probably worth it
};
then, write up your own make_unique<T>(Args&&...) (a std one is coming in C++1y), and use it like this:
Interface:
SomeAlgorithm(std::unique_ptr<InterfaceForDependencyStuff> pDependencyStuff)
Use:
SomeAlgorithm foo(std::make_unique<ImplementationForDependencyStuff>( blah blah blah ));
If you don't want virtual ~InterfaceForDependencyStuff() and want to use unique_ptr, you have to use a unique_ptr that stores its deleter (by passing in a stateful deleter).
On the other hand, if std::shared_ptr already comes with a make_shared, and it stores its deleter statefully by default. So if you go with shared_ptr storage of your interface, you get:
SomeAlgorithm(std::shared_ptr<InterfaceForDependencyStuff> pDependencyStuff)
and
SomeAlgorithm foo(std::make_shared<ImplementationForDependencyStuff>( blah blah blah ));
and make_shared will store a pointer-to-function that deletes ImplementationForDependencyStuff that will not be lost when you convert it to a std::shared_ptr<InterfaceForDependencyStuff>, so you can safely lack a virtual destructor in InterfaceForDependencyStuff. I personally would not bother, and leave virtual ~InterfaceForDependencyStuff there.
In most cases you don't want or need ownership transfer, it makes code harder to understand and less flexible (moved-from objects can't be reused). The typical case would be to keep ownership with the caller:
class SomeAlgorithm {
DistanceCalculator* distanceCalculator;
public:
explicit SomeAlgorithm(DistanceCalculator* distanceCalculator_)
: distanceCalculator(distanceCalculator_) {
if (distanceCalculator == nullptr) { abort(); }
}
double calculateComplicated() {
...
double dist = distanceCalculator->distance(p1, p2);
...
}
// Default special members are fine.
};
int main() {
EuclideanDistanceCalculator distanceCalculator;
SomeAlgorithm algorithm(&distanceCalculator);
algorithm.calculateComplicated();
}
Raw pointers are fine to express non-ownership. If you prefer you can use a reference in the constructor argument, it makes no real difference. However, don't use a reference as data member, it makes the class unnecessarily unassignable.
The down side of just using any pointer (smart or raw), or even an ordinary C++ reference, is that they allow calling non-const methods from a const context.
For stateless classes with a single method that is a non-issue, and std::function is a good alternative, but for the general case of classes with state or multiple methods I propose a wrapper similar but not identical to std::reference_wrapper (which lacks the const safe accessor).
template<typename T>
struct NonOwningRef{
NonOwningRef() = delete;
NonOwningRef(T& other) noexcept : ptr(std::addressof(other)) { };
NonOwningRef(const NonOwningRef& other) noexcept = default;
const T& value() const noexcept{ return *ptr; };
T& value() noexcept{ return *ptr; };
private:
T* ptr;
};
usage:
class SomeAlgorithm {
NonOwningRef<DistanceCalculator> distanceCalculator;
public:
SomeAlgorithm(DistanceCalculator& distanceCalculator_)
: distanceCalculator(distanceCalculator_) {}
double calculateComplicated() {
double dist = distanceCalculator.value().distance(p1, p2);
return dist;
}
};
Replace T* with unique_ptr or shared_ptr to get owning versions. In this case, also add move construction, and construction from any unique_ptr<T2> or shared_ptr<T2> ).
I'm trying to create and initialize a class that contains a member array of a non-trivial class, which contains some state and (around some corners) std::atomic_flag. As of C++11 one should be able to initialize member arrays.
The code (stripped down to minimum) looks like this:
class spinlock
{
std::atomic_flag flag;
bool try_lock() { return !flag.test_and_set(std::memory_order_acquire); }
public:
spinlock() : flag(ATOMIC_FLAG_INIT){};
void lock() { while(!try_lock()) ; }
void unlock() { flag.clear(std::memory_order_release); }
};
class foo
{
spinlock lock;
unsigned int state;
public:
foo(unsigned int in) : state(in) {}
};
class bar
{
foo x[4] = {1,2,3,4}; // want each foo to have different state
public:
//...
};
If I understand the compiler output correctly, this seems not to construct the member array, but to construct temporaries and invoke the move/copy constructor, which subsequently calls move constructors in sub-classes, and that one happens to be deleted in std::atomic_flag. The compiler output that I get (gcc 4.8.1) is:
[...] error: use of deleted function 'foo::foo(foo&&)'
note: 'foo::foo(foo&&)' is implicitly deleted because the default definition would be ill-formed
error: use of deleted function 'spinlock::spinlock(spinlock&&)'
note: 'spinlock::spinlock(spinlock&&)' is implicitly deleted because [...]
error: use of deleted function 'std::atomic_flag::atomic_flag(const std::atomic_flag&)'
In file included from [...]/i686-w64-mingw32/4.8.1/include/c++/atomic:41:0
[etc]
If I remove the array and instead just put a single foo member inside bar, I can properly initialize it using standard constructor initializers, or using the new in-declaration initialization, no problem whatsoever. Doing the same thing with a member array fails with the above error, no matter what I try.
I don't really mind that array elements are apparently constructed as temporaries and then moved rather than directly constructed, but the fact that it doesn't compile is obviously somewhat of a showstopper.
Is there a way I either force the compiler to construct (not move) the array elements, or a way I can work around this?
Here's a minimal example exposing the problem:
struct noncopyable
{
noncopyable(int) {};
noncopyable(noncopyable const&) = delete;
};
int main()
{
noncopyable f0 = {1};
noncopyable f1 = 1;
}
Although the two initializations of f0 and f1 have the same form (are both copy-initialization), f0 uses list-initialization which directly calls a constructor, whereas the initialization of f1 is essentially equivalent to foo f1 = foo(1); (create a temporary and copy it to f1).
This slight difference also manifests in the array case:
noncopyable f0[] = {{1}, {2}, {3}, {4}};
noncopyable f1[] = {1, 2, 3, 4};
Aggregate-initialization is defined as copy-initialization of the members [dcl.init.aggr]/2
Each member is copy-initialized from the corresponding initializer-clause.
Therefore, f1 essentially says f1[0] = 1, f1[1] = 2, .. (this notation shall describe the initializations of the array elements), which has the same problem as above. OTOH, f0[0] = {1} (as an initialization) uses list-initialization again, which directly calls the constructor and does not (semantically) create a temporary.
You could make your converting constructors explicit ;) this could avoid some confusion.
Edit: Won't work, copy-initialization from a braced-init-list may not use an explicit constructor. That is, for
struct expl
{
explicit expl(int) {};
};
the initialization expl e = {1}; is ill-formed. For the same reason, expl e[] = {{1}}; is ill-formed. expl e {1}; is well-formed, still.
Gcc refuses to compile list-initialization of arrays of objects with virtual destructor up to version 10.2. In 10.3 that was fixed.
E.g. if noncopyable from #dyp answer had a virtual destructor, gcc fails to compile line:
noncopyable f0[] = {{1}, {2}, {3}, {4}};
arguing to deleted copy and move c-rs. But successfully compiles under 10.3 and higher.