Wrapping smart pointers with method replacement - c++

I'm trying to write a smart pointer wrapper (contains a boost shared_ptr or scoped_ptr or another smart pointer wrapper); each wrapper type injects a bit of extra functionality (eg. logging usage, lazy init, verifying correct construction/destruction order, etc) but I want them to be as invisible as possible to the user (such that I could swap in/out wrappers simply by changing a single typedef, and possibly some constructor code, but none of the usage code).
Normal usage is trivial:
template<typename T>
class some_smart_ptr_wrapper
{
public:
typedef typename T::value_type value_type;
...
value_type* get() { /*do something magic*/ return m_ptr.get(); }
const value_type* get() const { /*do something magic*/ return m_ptr.get(); }
// repeat for operator->, operator*, and other desired methods
private:
T m_ptr;
};
typedef some_smart_ptr_wrapper< boost::shared_ptr<int> > smart_int;
smart_int p;
(Now all other code can use p indistinguishably from a shared_ptr, at least for the defined operations, and I can add extra wrappers just by changing the typedef.)
Multiple wrappers can be used simultaneously simply by nesting them as you'd expect, and only the code that declares (and sometimes initialises) the variable needs to care.
Occasionally though it's useful to be able to get the "basic" shared/scoped_ptr from a wrapper (particularly to pass a shared_ptr as an argument to a function that doesn't need to trigger the functionality added by the wrappers); for a single wrapper layer it's easy:
T& getPtr() { return m_ptr; }
const T& getPtr() const { return m_ptr; }
But this doesn't scale nicely to multiple wrapper layers (the caller has to do p.getPtr().getPtr().getPtr() the correct number of times).
What I'd like to be able to do is to declare getPtr() such that:
if T implements getPtr(), then it returns m_ptr.getPtr() (whatever type that is).
if T does not implement getPtr(), then it returns m_ptr.
it's still available in both const and non-const flavours, as you'd expect.
The net result of which is that a single call to getPtr() from the outside code will "walk up" the chain to the original smart pointer, since that will be the only one that doesn't implement getPtr().
I'm fairly sure that the solution will involve SFINAE and boost::enable_if; I've had a bit of a play towards trying to get something like that to work but haven't had much luck thus far.
Solutions or completely alternate approaches both welcomed; note that I would like it to work in both VC++2008 and GCC (ie. no C++11, sadly).

(1) Declare a special member typename which is unique inside:
template<typename T>
class some_smart_ptr_wrapper
{
public:
typedef T smart_type; // <-- unique name
...
};
(2) Wrap getPtr() inside a template function wrapper:
template<typename T>
class some_smart_ptr_wrapper
{
...
public:
T& getPtr () { return m_ptr; }
typename My_sfinae<T>::RealType& getFinalPtr ()
{ return My_sfinae<T>::getPtr(m_ptr); }
...
};
(3) Where My_sfinae is implemented as usual:
template<typename T>
struct void_ { typedef void type; };
template<typename T, typename = void>
struct My_sfinae {
typedef T RealType;
static T& getPtr (T &p) { return p; }
}; //^^^^^^^^^ business logic!
template<typename T>
struct My_sfinae<T, typename void_<typename T::smart_type>::type> {
typedef typename My_sfinae<typename T::smart_type>::RealType RealType;
static RealType& getPtr (T &p)
{ return My_sfinae<typename T::smart_type>::getPtr(p.getPtr()); }
};
As you can see, My_sfinae removes all your wrappers recursively and finally you are left with the final m_ptr.
Here is the demo.

It is, actually, a simple problem: just use Overloading :)
template <typename T>
boost::scoped_ptr<T>& get_pointer(boost::scoped_ptr<T>& sp) { return sp; }
template <typename T>
boost::shared_ptr<T>& get_pointer(boost::shared_ptr<T>& sp) { return sp; }
// One overload per "wrapper"
template <typename T>
typename get_pointer_type<T>::type& get_pointer(some_wrapper<T>& p) {
return get_pointer(p.getPtr());
}
The trick is then to correctly specialize get_pointer_type for each wrapper.
template <typename T>
struct get_pointer_type { typedef T type; };
template <typename T>
struct get_pointer_type< some_wrapper<T> > {
typedef typename get_pointer_type<T>::type type;
};

The closest thing that comes to my mind is the paper written by Bjarne Stroustrup called Wrapping C++ Member Function Calls.
This paper presents a simple, general, and efficient solution to the old problem of
‘‘wrapping’’ calls to an object in pairs of prefix and suffix code. The solution is also
non-intrusive, applies to existing classes, allows the use of several prefix/suffix pairs, and
can be implemented in 15 simple lines of Standard C++. A robust version of the wrapper
is also presented. The claim of efficiency is backed by measurement.

Related

Getting memory address in c++ without ampersand (&) operator

I am implementing a default allocator for a simple containers library I'm writing, and I want to add an addressing-method that gets the memory address of the variable x that it works on, and that is also safe to use when x has overloaded the &-operator.
Looking into the MSVC STL source code I see that the function __builtin_addressof(your_variable) is used. Is this the only way? I also discovered the address method has been removed from the STL allocator in C++20, but I do not know if this was due to it not being used, or if there is a new and better method.
My implementation looks something like this:
namespace mem_core {
template <typename T>
const T* addressof(T& argument) noexcept {
return __builtin_addressof(argument);
}
template <typename T>
const T* addressof(T&& arg) = delete;
//... more mem_core stuff
} //namespace mem_core end
template <typename T>
class allocator : public mem_core::base_allocator<T> { // refers to base_allocator interface
public:
T* address(T& value) noexcept {
return mem_core::addressof(value);
}
}
There is std::addressof for exactly this purpose

C++ check type of template instance variable

I have use case similar to this question
I want to check what type of instance variable is stored in parameter without throwing an exception
class ParameterBase
{
public:
virtual ~ParameterBase() {}
template<class T> const T& get() const; //to be implimented after Parameter
template<class T, class U> void setValue(const U& rhs); //to be implimented after Parameter
};
template <typename T>
class Parameter : public ParameterBase
{
public:
Parameter(const T& rhs) :value(rhs) {}
const T& get() const {return value;}
void setValue(const T& rhs) {value=rhs;}
private:
T value;
};
//Here's the trick: dynamic_cast rather than virtual
template<class T> const T& ParameterBase::get() const
{ return dynamic_cast<const Parameter<T>&>(*this).get(); }
template<class T, class U> void ParameterBase::setValue(const U& rhs)
{ return dynamic_cast<Parameter<T>&>(*this).setValue(rhs); }
class Diagram
{
public:
ParameterBase* v;
int type;
};
What I want to be able to do is something like this
if (diagram.getParameter().type == int) {
}
How can I change this implementation so it will allow me to peek what type of Parameter is holding
Thanks for the answers , few more points
I am on C++ 11 so cannot use variant or any
Is there standard way of doing this. All I want is an instance variable of class that can be of multiple types (bounded) and while reading it check what type it is
The Simple Fix
The simple solution to your problem is to add a template function is<T>() to your ParameterBase that is defined in terms of dynamic_cast on a pointer. dynamic_cast with pointers return nullptr on failure, unlike references which will throw a std::bad_cast. For example:
class ParameterBase
{
public:
...
template <typename T>
bool is() const;
};
...
template <typename T>
bool ParameterBase::is() const
{
return dynamic_cast<const Parameter<T>*>(this) != nullptr;
}
The use would be simply:
if (diagram.getParameter().is<int>()) {
...
}
Note, however, that this whole design is not particularly nice. It has a cyclic dependency between the base and derived in a way that is highly coupled. Additionally it requires ParameterBase to exist as a pointer in order to operate correctly; where value-semantics would be much more coherent (if possible)
It would be better if you can use type-erasure, even if you define Parameter in terms of it (this is what C++17's std::any will do for you). The second answer in your linked question already describes what this may look like.
Type-erased Solution (c++11)
This uses C++11 features like forwarding references, rvalue-references, and unique_ptr -- but the concept can also be applied to earlier C++ versions.
For type-erasure, you would need an interface that encompasses at least these 2 features:
getting a reference to the templated type, and
getting an identifier for the current type.
Since interfaces in C++ can't be virtual, we have to get creative about returning the reference. C++ has void* which can be any kind of pointer. This can be bad if misused (such as casting between the wrong type); but if we know the underlying type, can be perfect. Thankfully here, we know the underlying type.
A quick form of type-erasure could be achieved with the following:
#include <type_traits> // std::decay
#include <utility> // std::forward
#include <typeinfo> // std::type_info, std::bad_cast
#include <memory> // std::unique_ptr
class Parameter
{
private:
// This is the interface we will implement in all instances
struct Interface {
virtual ~Interface() = default;
virtual void* get() = 0;
virtual const std::type_info& type() const = 0;
};
// This is the concrete instantiation of the above interfaces
template <typename T>
struct Concrete : public Interface {
template <typename U>
Concrete(U&& u) : m_value{std::forward<U>(u)} {}
void* get() { return &m_value; }
const std::type_info& type() const { return typeid(T); }
T m_value; // actually holds the value here
};
// This holds onto the interface, and only the interface
std::unique_ptr<Interface> m_interface;
public:
// Constructs a parameter and sets the first interface value
template <typename T>
explicit Parameter(T&& value)
: m_interface{new Concrete<typename std::decay<T>::type>{std::forward<T>(value)}}
{}
Parameter(Parameter&&) = default;
Parameter& operator=(Parameter&&) = default;
// Check if we are the same type by comparing the typeid
template <typename T>
bool is() const {
return typeid(T) == m_interface->type();
}
// Get the underlying value. Always check that we are the correct type first!
template <typename T>
const T& get() const {
// do the error handling ourselves
if (!is<T>()) { throw std::bad_cast{}; }
// cast void* to the underlying T*. We know this is safe
// because of our check above first
return (*static_cast<T*>(m_interface->get()));
}
// Set the underlying value. Always check that we are the correct type first!
template <typename T, typename U>
void set(U&& value) {
// do the error handling ourselves
if (!is<T>()) { throw std::bad_cast{}; }
(*static_cast<T*>(m_interface->get())) = std::forward<U>(value);
}
};
In the above, we take on the burden of detecting the underlying type ourselves -- but we remove the cyclic coupling. We now also have a proper value-type that we can move around like a normal variable, which is really helpful since it allows us to return this object from APIs without worrying about lifetime or ownership.
If copyability is desired as well, the interface can be extended to have a clone() function or something to return copies
Using this object, the code becomes:
if (parameter.is<int>()) {
/* treat parameter as an int */
}
Here's a small working example.
Type-erased Solution (c++17)
If you're looking for a finite set of instantiations, std::variant may be used for this purpose. If the number of possibly underlying types is unbounded, you should look into std::any
In either case, the use of a hierarchy here is superficial (at least in the current example) since the entire type-erasure can be reduced to a singular type with the ability to query the containment. This could be done easily, using std::any as an example:
#include <any> // std::any, std::any_cast
class Parameter
{
public:
// This implementation changes the active type if 'T' is not the same as the stored
// value. If you want to restrict this, you can do error checking here instead.
template <typename T>
void set(const T& value) { m_value = value; }
template <typename T>
const T& get() { return std::any_cast<const T&>(m_value); }
template <typename T>
bool is() const noexcept { return m_value.type() == typeid(T); }
private:
std::any m_value;
};
If you don't want the active member to change, this could be restricted by checking is<T>() first and handling the error somehow.
Querying the active type can be achieved simply by doing:
if (parameter.is<int>()) {
/* treat parameter as an int */
}
If the types are fixed, you can always use std::variant instead using std::has_alternative for the definition of is
Looks like you know in advance all possible types for the parameter (I'm saying that because you have a type field that is expected to be used as an enumeration). If that is the case, you may use the std::variant idiom:
class Diagram
{
public:
std::variant<Parameter<int>, Parameter<std::string>> v;
};
In this case you may use this code to get known the actual type:
switch(v.index()) {
case 0:
// int is used
case 1:
// string is used
}
For sure there are other alternatives. For example, if you have something of a type and you need to test if that is the type expect, you my use std::is_same template:
template <typename T>
class Parameter : public ParameterBase
{
public:
bool isOfTypeInt() const {
return std::is_same_v<T, int>;
}
private:
T value;
};

std::function/bind like type-erasure without Standard C++ library

I'm developing a simple event driven application in C++11 based on the publish/subscribe pattern. Classes have one or more onWhateverEvent() method invoked by the event loop (inversion of control). Since the application is in fact a firmware, where code size is critical and flexibility is not of high priority, the 'subscribe' part is a simple table with event id's and associated handlers.
Here's a very simplified code of the idea:
#include <functional>
enum Events {
EV_TIMER_TICK,
EV_BUTTON_PRESSED
};
struct Button {
void onTick(int event) { /* publish EV_BUTTON_PRESSED */ }
};
struct Menu {
void onButtonPressed(int event) { /* publish EV_SOMETHING_ELSE */ }
};
Button button1;
Button button2;
Menu mainMenu;
std::pair<int, std::function<void(int)>> dispatchTable[] = {
{EV_TIMER_TICK, std::bind(&Button::onTick, &button1, std::placeholders::_1) },
{EV_TIMER_TICK, std::bind(&Button::onTick, &button2, std::placeholders::_1) },
{EV_BUTTON_PRESSED, std::bind(&Menu::onButtonPressed, &mainMenu, std::placeholders::_1) }
};
int main(void)
{
while(1) {
int event = EV_TIMER_TICK; // msgQueue.getEventBlocking();
for (auto& a : dispatchTable) {
if (event == a.first)
a.second(event);
}
}
}
This compiles and runs fine with a desktop compiler, and std:function<void(int)>> fn = std::bind(&SomeClass::onSomething), &someInstance, std::placeholders::_1) elegantly implements type erasure so the event dispatch table can hold handlers of different classes, thus different types.
The problem comes with the embedded compiler (AVR-GCC 4.8.3) which supports C++11, but there's no Standard C++ Library: no <functional> header. I was thinking how can I re-create the above behavior with compiler features only. I evaluated a few options, but there are objections for each (by the compiler or me):
Create an interface with a virtual void Handler::onEvent(int event) method, and derive Button and Menu from it. The dispatch table can hold interface pointers, and virtual method calls do the rest. This is the most simple approach but I don't like the idea of limiting the number of event handler methods to one per class (with doing local if-else event dispatch), and having the overhead of a virtual method call per event.
My second idea still contains a virtual method call, but has no restrictions on the Button and Menu class. It's a virtual method call based type-erasure with functors:
struct FunctBase {
virtual void operator()(int event) = 0;
};
template<typename T>
struct Funct : public FunctBase
{
T* pobj; //instance ptr
void (T::*pmfn)(int); //mem fun ptr
Funct(T* pobj_, void (T::*pmfn_)(int)) : pobj(pobj_), pmfn(pmfn_) {}
void operator()(int ev) override {
(pobj->*pmfn)(ev);
}
};
Funct can hold instance and method pointers, and the dispatch table can be constructed of FunctBase pointers. This way table is as flexible as with function/bind: can hold any class (type) and any number of handlers per class. My only problem that it still contains 1 virtual method call per event, it's just moved to the functor.
My third idea is a simple hack converting method pointers to function pointers:
typedef void (*Pfn)(void*, int);
Pfn pfn1 = reinterpret_cast<Pfn>(&Button::onTick);
Pfn pfn2 = reinterpret_cast<Pfn>(&Menu::onButtonPressed);
As far as I know this is Undefined Behavior and indeed makes the compiler emit a big fat warning. It's based on the assumption that c++ methods have an implicit 1st argument pointing to this. Nonetheless it works, it's lightweight (no virtual calls), and it's flexible.
So my question: Is it possible to do something like option 3 in clean C++ way? I know there's a void* based type-erasure technique (opposed to virtual method call in option 2), but I don't know how to implement it. Looking at desktop version with std::bind also gives me the impression that it binds the first implicit argument to be the instance pointer, but maybe that's just the syntax.
A solid, efficient, std::function<R(Args...)> replacement isn't hard to write.
As we are embedded, we want to avoid allocating memory. So I'd write a small_task< Signature, size_t sz, size_t algn >. It creates a buffer of size sz and alignment algn in which it stores its erased objects.
It also stores a mover, a destroyer, and an invoker function pointer. These pointers can either be locally within the small_task (maximal locality), or within a manual struct vtable { /*...*/ } const* table.
template<class Sig, size_t sz, size_t algn>
struct small_task;
template<class R, class...Args, size_t sz, size_t algn>
struct small_task<R(Args...), sz, algn>{
struct vtable_t {
void(*mover)(void* src, void* dest);
void(*destroyer)(void*);
R(*invoke)(void const* t, Args&&...args);
template<class T>
static vtable_t const* get() {
static const vtable_t table = {
[](void* src, void*dest) {
new(dest) T(std::move(*static_cast<T*>(src)));
},
[](void* t){ static_cast<T*>(t)->~T(); },
[](void const* t, Args&&...args)->R {
return (*static_cast<T const*>(t))(std::forward<Args>(args)...);
}
};
return &table;
}
};
vtable_t const* table = nullptr;
std::aligned_storage_t<sz, algn> data;
template<class F,
class dF=std::decay_t<F>,
// don't use this ctor on own type:
std::enable_if_t<!std::is_same<dF, small_task>{}>* = nullptr,
// use this ctor only if the call is legal:
std::enable_if_t<std::is_convertible<
std::result_of_t<dF const&(Args...)>, R
>{}>* = nullptr
>
small_task( F&& f ):
table( vtable_t::template get<dF>() )
{
// a higher quality small_task would handle null function pointers
// and other "nullable" callables, and construct as a null small_task
static_assert( sizeof(dF) <= sz, "object too large" );
static_assert( alignof(dF) <= algn, "object too aligned" );
new(&data) dF(std::forward<F>(f));
}
// I find this overload to be useful, as it forces some
// functions to resolve their overloads nicely:
// small_task( R(*)(Args...) )
~small_task() {
if (table)
table->destroyer(&data);
}
small_task(small_task&& o):
table(o.table)
{
if (table)
table->mover(&o.data, &data);
}
small_task(){}
small_task& operator=(small_task&& o){
// this is a bit rude and not very exception safe
// you can do better:
this->~small_task();
new(this) small_task( std::move(o) );
return *this;
}
explicit operator bool()const{return table;}
R operator()(Args...args)const{
return table->invoke(&data, std::forward<Args>(args)...);
}
};
template<class Sig>
using task = small_task<Sig, sizeof(void*)*4, alignof(void*) >;
live example.
Another thing missing is a high quality void(Args...) that doesn't care if the passed-in callable has a return value.
The above task supports move, but not copy. Adding copy means that everything stored must be copyable, and requires another function in the vtable (with an implementation similar to move, except src is const and no std::move).
A small amount of C++14 was used, namely the enable_if_t and decay_t aliases and similar. They can be easily written in C++11, or replaced with typename std::enable_if<?>::type.
bind is best replaced with lambdas, honestly. I don't use it even on non-embedded systems.
Another improvement would be to teach it how to deal with small_tasks that are smaller/less aligned by storing their vtable pointer rather than copying it into the data buffer, and wrapping it in another vtable. That would encourage using small_tasks that are just barely large enough for your problem set.
Converting member functions to function pointers is not only undefined behavior, often the calling convention of a function is different than a member function. In particular, this is passed in a particular register under some calling conventions.
Such differences can be subtle, and can crop up when you change unrelated code, or the compiler version changes, or whatever else. So I'd avoid that unless you have little other choice.
As noted, the platform lacks libraries. Every use of std above is tiny, so I'll just write them:
template<class T>struct tag{using type=T;};
template<class Tag>using type_t=typename Tag::type;
using size_t=decltype(sizeof(int));
move
template<class T>
T&& move(T&t){return static_cast<T&&>(t);}
forward
template<class T>
struct remove_reference:tag<T>{};
template<class T>
struct remove_reference<T&>:tag<T>{};
template<class T>using remove_reference_t=type_t<remove_reference<T>>;
template<class T>
T&& forward( remove_reference_t<T>& t ) {
return static_cast<T&&>(t);
}
template<class T>
T&& forward( remove_reference_t<T>&& t ) {
return static_cast<T&&>(t);
}
decay
template<class T>
struct remove_const:tag<T>{};
template<class T>
struct remove_const<T const>:tag<T>{};
template<class T>
struct remove_volatile:tag<T>{};
template<class T>
struct remove_volatile<T volatile>:tag<T>{};
template<class T>
struct remove_cv:remove_const<type_t<remove_volatile<T>>>{};
template<class T>
struct decay3:remove_cv<T>{};
template<class R, class...Args>
struct decay3<R(Args...)>:tag<R(*)(Args...)>{};
template<class T>
struct decay2:decay3<T>{};
template<class T, size_t N>
struct decay2<T[N]>:tag<T*>{};
template<class T>
struct decay:decay2<remove_reference_t<T>>{};
template<class T>
using decay_t=type_t<decay<T>>;
is_convertible
template<class T>
T declval(); // no implementation
template<class T, T t>
struct integral_constant{
static constexpr T value=t;
constexpr integral_constant() {};
constexpr operator T()const{ return value; }
constexpr T operator()()const{ return value; }
};
template<bool b>
using bool_t=integral_constant<bool, b>;
using true_type=bool_t<true>;
using false_type=bool_t<false>;
template<class...>struct voider:tag<void>{};
template<class...Ts>using void_t=type_t<voider<Ts...>>;
namespace details {
template<template<class...>class Z, class, class...Ts>
struct can_apply:false_type{};
template<template<class...>class Z, class...Ts>
struct can_apply<Z, void_t<Z<Ts...>>, Ts...>:true_type{};
}
template<template<class...>class Z, class...Ts>
using can_apply = details::can_apply<Z, void, Ts...>;
namespace details {
template<class From, class To>
using try_convert = decltype( To{declval<From>()} );
}
template<class From, class To>
struct is_convertible : can_apply< details::try_convert, From, To > {};
template<>
struct is_convertible<void,void>:true_type{};
enable_if
template<bool, class=void>
struct enable_if {};
template<class T>
struct enable_if<true, T>:tag<T>{};
template<bool b, class T=void>
using enable_if_t=type_t<enable_if<b,T>>;
result_of
namespace details {
template<class F, class...Args>
using invoke_t = decltype( declval<F>()(declval<Args>()...) );
template<class Sig,class=void>
struct result_of {};
template<class F, class...Args>
struct result_of<F(Args...), void_t< invoke_t<F, Args...> > >:
tag< invoke_t<F, Args...> >
{};
}
template<class Sig>
using result_of = details::result_of<Sig>;
template<class Sig>
using result_of_t=type_t<result_of<Sig>>;
aligned_storage
template<size_t size, size_t align>
struct alignas(align) aligned_storage_t {
char buff[size];
};
is_same
template<class A, class B>
struct is_same:false_type{};
template<class A>
struct is_same<A,A>:true_type{};
live example, about a dozen lines per std library template I needed.
I would put this "std library reimplementation" into namespace notstd to make it clear what is going on.
If you can, use a linker that folds identical functions together, like the gold linker. template metaprogramming can cause binary bloat without a solid linker to strip it.
Your 1st idea is your typical object oriented solution to the problem. It's perfectly fine, but a bit heavy-handed - not quite as usable as std::function. Your 3rd idea is undefined behavior. Nope nope nope.
Your 2nd idea - now there's something we can work with! This is close to how std::function is actually implemented. We can write a class that can take any object that is callable with int and returns void:
class IntFunc {
private:
struct placeholder {
virtual ~placeholder() = default;
virtual void call(int ) = 0;
};
template <typename F>
struct holder : placeholder {
holder(F f) : func(f) { }
void call(int i) override { func(i); }
F func;
};
// if you wrote your own unique_ptr, use it here
// otherwise, will have to add rule of 5 stuff
placeholder* p;
public:
template <typename F>
IntFunc(F f)
: placeholder(new holder<F>(f))
{ }
template <typename Cls>
IntFunc(Cls* instance, void (Cls::*method)(int )) {
auto lambda = [=](int i){ (instance->*method)(i); };
placeholder = new holder<decltype(lambda)>(lambda);
}
void operator()(int i) {
p->call(i);
}
};
With that, you basically have std::function<void(int)> in a usable, generic way.
Now a 4th idea might be to just extend your 3rd idea to something usable. Actually use function pointers:
using Pfn = void (*)(void*, int);
And then use lambdas to make such things:
Pfn buttonOnTick = [](void* ctxt, int i){
static_cast<Button*>(ctxt)->onTick(i);
};
But then you have to hold on to the contexts somehow - which adds extra work.
Before I try to write all the STL stuff by hand, I try to use the STL which I already have from the compiler itself. Because most of the STL code you use is header only, I simply include it and do some minor hacks to get them compiled. In fact id did 10 minutes to get it ready to link!
I used avr-gcc-5.2.0 version without any problems for the task. I have no old installation and I believe it is easier to install the actual version in some minutes instead of fixing problems from the old one.
After compile your example code for avr I got link errors:
build-check-std-a520-nomemdbg-os-dynamic-noncov/main.o: In function `std::__throw_bad_function_call()':
/home/krud/own_components/avr_stl/avr_stl009/testing/main.cpp:42: undefined reference to `operator delete(void*, unsigned int)'
/home/krud/own_components/avr_stl/avr_stl009/testing/main.cpp:42: undefined reference to `operator delete(void*, unsigned int)'
collect2: error: ld returned 1 exit status
Simply write your own __throw_bad_function_call and get rid of the link problem.
For me it makes really no sense to write a own STL implementation. Here I simply used the headers which comes from the compiler installation ( gcc 5.2.0).

Raise an exception for non-pointer template class?

I've got this queue class, actually, several that suffer from the same issue - performance will be poor if compiled with a type that has a lengthy copy ctor - the queue is locked during push/pop and the longer it is locked, the greater the chance of contention. It would be useful if the class would not compile if some developer tried to compile it with a 10MB buffer class, (instead of a pointer to it).
It seems that there is no easy way to restrict template parameters to base classes or any other type.
Is there some bodge I can use so that my class will not compile if the parameter is not a pointer to a class instance?
You can do this in several ways. As another answer points out you can do it with a static_assert (preferably from C++11/Boost although you can roll your own), although I'd recommend checking if it is actually a pointer and not just relying on the size. You can either roll your own or use an existing trait (available in C++11 too) depending on what system you're using:
template <typename T>
struct is_pointer {
enum { value = 0 };
};
template <typename T>
struct is_pointer<T*> {
enum { value = 1 };
};
template <typename T>
struct container {
static_assert(is_pointer<T>::value, "T must be a pointer");
void push(const T&);
T pop();
};
struct foo {};
int main() {
container<foo*> good;
container<foo> fail;
}
But that raises a bigger point. If your requirement is that you only ever point to things, why not interpret the template parameter like that to begin with? E.g. make your container:
template <typename T>
struct container {
void push(const T*);
T *pop();
};
instead of allowing people to specify non-pointer types in the first place?
Finally if you don't want to go down the static_assert road you can just specialise the container for pointer types only and not implement it for non-pointers, e.g.:
template <typename T>
struct container;
template <typename T>
struct container<T*> {
void push(const T*);
T *pop();
};
struct foo {};
int main() {
container<foo*> good;
container<foo> fail;
}
This still requires explicitly making the type a pointer, still causes compile time failure for non-pointer types, but doesn't need a static_assert or way of determining if a type is a pointer.
"Is there some bodge I can use so that my class will not compile if the parameter is not a pointer to a class instance?"
Not a bodge, but:
template<class T>
class MyContainer
{
public:
void AllMemberFunctions( T* in ){}
void OnlyAcceptTStars( T* in ){}
};
The user defines the type being held, and your functions only accept or handle pointers to that type.
(Or do what STL does, assume some intelligence on the part of the user and forget about the issue.)
Use a variant of static assert (just google for many possible implementations). Something like BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(void*)) should do the trick.
Yes, you can do it using static_assert. For example,
template<int N>
class Queue
{
static_assert(N < size, "N < size violated");
...
};

Downside of this macro construct and possible alternatives

I recently saw some code using macros like
#define CONTAINS(Class, Name)\
private:\
std::list<Class> m_##Name##s;\
public:\
void add_##Name(const Class& a_##Name) {\
m_##Name##s.push_back(a_##Name);\
}\
int get_##Name(int pos) {\
return m_##Name##s.at(pos);\
}\
// ... more member functions
Later you can declare a class like
class my_class {
CONTAINS(int, integer)
// ...
};
and write
my_class a(...);
a.add_integer(10);
I was puzzled about this paste-in-macro-style because I'm missing concrete counter-arguments. But beside that I accept the following pros
you can easily add a list interface for arbitrary types to your class
you avoid frequently repeated code
you have an easy to use interface (like add_integer(10))
Now I'm searching for alternatives which meet all these points above and avoid this old C macro style. My first idea was to create an abstract base class template
template<typename T>
class list_interface {
private:
std::list<T> m_list;
public:
void add_element(const T& x) {
m_list.push_back(x);
}
// ... more member functions
};
and add it to my class via inheritance like this
class my_class : public list_interface<int> {
// ...
};
Now I can write too
my_class a;
a.add_element(10);
but I'm concerned about the following points:
you can only add one list to your class
you publicly inherit from a class without virtual destructor
I don't meet the third point of the pros (add_element(10) instead of add_integer(10))
My questions are:
What are the drawbacks of the old C macro construct
How can I provide a similar functionality without macros
How about:
#include <vector>
template<typename T>
class Plop
{
std::vector<T> data;
public:
void add(T const& v) {data.push_back(v);}
T get(int pos) {return data.at(pos);} // at() is not valid on lists.
};
class my_class
{
public:
Plop<int> integer;
Plop<float> floater;
};
int main()
{
my_class x;
x.integer.add(5); // similar to x.add_integer(5);
x.integer.get(0); // similar to x.get_integer(0);
}
It meets all the requirements:
you can easily add a list interface for arbitrary types to your class
you avoid frequently repeated code
you have an easy to use interface (like add_integer(10))
My questions are:
What are the drawbacks of the old C macro construct
The ick factor.
Debugging.
Can pass individual list to other functions or methods.
How can I provide a similar functionality without macros
See above.
my opinion
1) Yuck yuck. Complex macro which will hinder debugging. Just the view of the macro makes my skin crawl.
2) Your inheritance solution looks fine. If you really needed multiple lists of different types, you might want to consider just writing more code and instantiating the list as a member variable. There really is no benefit of attempting to reduce lines of code by making it convoluted.
There is a way, in meta-programming fashion, and using tags.
First, let's consider the roll your own solution.
The idea is to come up with this interface:
class my_class : public vector<Name, std::string>, public vector<Foo, int>
{
};
And then, to use it like this:
my_class a;
a.add<Name>("Peter");
a.add<Foo>(3);
Now, lets dive behind the covers. We are going to use SFINAE combined with enable_if.
template <class Tag, class Type>
class vector
{
template <class T, Return>
struct Enable
{
typedef typename boost::enable_if<
boost::is_same<T,Tag>,
Return
>::type type;
}; // Enable
public:
template <class T>
typename Enable<T,void>::type
add(Type const& i) { m_elements.push_back(i); }
template <class T>
typename Enable<T, Type const&>::type
get(size_t i) const { return m_elements.at(i); }
// You'd better declare a whole lot of other methods if you really want that
// like empty, size and clear at the very least.
// Just use the same construct for the return type.
protected:
vector() : m_elements() {}
vector(vector const& rhs) : m_elements(rhs.m_elements) {}
vector& operator=(vector const& rhs) { m_elements = rhs.m_elements; return *this; }
~vector() {} // Not virtual, because cannot be invoked publicly :)
private:
std::vector<Type> m_elements; // at() is inefficient on lists
};
How does this work ?
Basically when you invoke get<Name> the compiler has 2 alternatives:
vector<Name,std::string>::get
vector<Foo,int>::get
Now, thanks to enable_if, the second alternative is ill-formed (the type deduced cannot be used because Foo != Name), and thus, thanks to SFINAE, this alternative is removed from the list without any complaint.
Then, since there is only one alternative, it gets selected. And of course, since this is done at compile-time, you don't actually have any runtime penalty.
If you want to skip some work (for this type). You could also simply use a simpler construct:
template <class Tag, class Embedded>
class Embed
{
// redeclares same private and protected interface
public:
template <class T>
typename Enable<T,Embedded &>::type get() { return m_element; }
template <class T>
typename Enable<T,Embedded const&>::type get() const { return m_element; }
private:
Embedded m_element;
};
Then you use it like so:
class my_class: public Embed< Names, std::vector<std::string> >,
public Embed<Foo,int>
{
};
my_class a;
std::vector<std::string> const& names = a.get<Names>();
int foo = a.get<Foo>();
a.get<Names>().push_back("Peter");
It's easier since you only provide accessors and don't have to write a whole bunch of methods just to forward the work.
And now that we've work so much, we should ask ourselves: this seems quite practical and generic, surely there is a library or something ?
There is >> Boost.Fusion's map:
class my_class
{
public:
template <class Tag>
typename result_of::at_key<map_type, T>::type &
get() { return at_key<T>(m_data); }
template <class Tag>
typename result_of::at_key<map_type, T>::type const&
get() const { return at_key<T>(m_data); }
private:
// First element of the pair: TAG
// Second element of the pair: Actual type of the data
typedef boost::fusion::map <
std::pair<Name, std::vector<std::string> >,
std::pair<Foo, int>
> map_type;
map_type m_data;
};
The main issue with the macro is: it is solving a problem you don't really have.
It is making a class with list members, where the lists are manipulated directly.
Because we think in OO, members should be encapsulated and we want to use DRY, we come to this construct, while my_class remains really a data-class.
If all the class has to do is contain lists, turn it into a struct and keep the lists public.
This way you have a clean intention and the lists can be accessed the STL-way.
If the class needs to have control over the lists, then you shouldn't expose the lists and the macro's are of little use.
So my code would be (not compiled):
struct my_class {
std::list<int> integers;
std::list<std::string> names;
// ...
};
int main()
{
my_class lists;
lists.integers.push_back(5);
size_t size_names = lists.names.size();
}
Pro:
easily add lists
no code duplication
consistent (STL) interface
straightforward
no macro's
Con:
no data encapsulation, if that would be a requirement
For multiple lists, you can try multiple inheritance with typedefs. Something like:
class my_class : public list_interface<int>, public list_interface<float> {
public:
typedef list_interface<int> Ints;
typedef list_interface<float> Floats;
//...
};
and use like:
my_class a;
a.Ints::add_element(10);
a.Floats::add_element(10.0f);