I'm trying to write a container class using boost::ptr_vector. Inside the ptr_vector I would like to include different classes. I'm trying to achieve that using static templates, but so far I'm not able to do that. For example, the container class is
class model {
private:
boost::ptr_vector<elem_type> elements;
public:
void insert_element(elem_type *a) {
element_list.push_back(a);
}
};
and what I'm trying to achieve is be able to use different elem_type classes. The code below doesn't satisfy my requirements:
template <typename T>class model {
private:
boost::ptr_vector<T> elements;
public:
void insert_element(T *a) {
element_list.push_back(a);
}
};
because when I initialize the container class I can only use one class as template:
model <elem_type_1> model_thing;
model_thing.insert_element(new elem_type_1)
but not elem_type_2:
model_thing.insert_element(new elem_type_2)//error, of course
It is possible to do something like using templates only on the member?
class model {
private:
template <typename T> boost::ptr_vector<T> elements;
public:
void insert_element(T *a) {
element_list.push_back(a);
}
}; //wrong
So I can call the insert_element on the specific class that I want to insert? Note that I do not want to use virtual members.
Thanks!
Try using a vector of boost::variant:
#include <iostream>
#include <vector>
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
struct Foo
{
Foo(int v=0) : a(v) {}
int a;
};
struct Bar
{
Bar(int v=0) : b(v) {}
int b;
};
struct print_visitor : public boost::static_visitor<>
{
void operator()(const Foo& foo) const
{
std::cout << "Foo " << foo.a << "\n";
}
void operator()(const Bar& bar) const
{
std::cout << "Bar " << bar.b << "\n";
}
};
int main()
{
typedef boost::variant<Foo, Bar> Variant;
std::vector<Variant> bag;
bag.push_back(Foo(123));
bag.push_back(Bar(456));
BOOST_FOREACH(const Variant& element, bag)
{
boost::apply_visitor(print_visitor(), element);
}
}
boost::variant's apply_visitor functions are useful for avoiding excessive casting back to the original type.
Vector is contains elements where each element has the same type as others. If you want to create vector of elements of different classes you could use vector of elements of type boost::any.
Related
How can I pass any object of an templated class to another function in C++11?
In the snippet below passInObj does not compile because it complains about Printer&. I want to pass in any Printer it does not matter which template T I have used.
How can I do this and why does the solution below not work?
#include <iostream>
#include <vector>
template <typename T>
class Printer {
public:
Printer(const T& tl) : t(tl) {}
void print() const {
for (auto x : t) {
std::cout << x << std::endl;
}
}
const T &t;
};
// THIS LINE DOES NOT COMPILE
void passInObj(const Printer& p) {
p.print();
}
int main() {
std::vector<std::string> vec;
vec.push_back("ABC");
Printer<std::vector<std::string>> printer(vec);
printer.print();
passInObj(p);
return 0;
}
How can I do this
You need to make it into a function template:
template <class T>
void passInObj(const Printer<T>& p) {
p.print();
}
Demo
and why does the solution below not work?
Because Printer is not a type, it's only a template. For passInObj to work with any Printer<T>, you need to make the function into a function template so that it'll be instantiated for every Printer<T> which is used to call it.
While #TedLyngmo's answer should be your go-to by default, you can also do this via a polymorphic interface if you cannot make passInObj() a template for some reason or other.
This is done by adding a base interface class that will be derived by all Printer<> classes:
#include <iostream>
#include <vector>
class IPrinter {
public:
virtual void print() const = 0;
// Either that or public and virtual
protected:
~IPrinter() = default;
};
template <typename T>
class Printer : public IPrinter {
public:
Printer(const T& tl) : t(tl) {}
void print() const override {
for (auto x : t) {
std::cout << x << std::endl;
}
}
const T &t;
};
void passInObj(const IPrinter& p) {
p.print();
}
int main() {
std::vector<std::string> vec;
vec.push_back("ABC");
Printer<std::vector<std::string>> printer(vec);
printer.print();
passInObj(p);
return 0;
}
I am in a situation where I am forced to use a std::vector container as my underlying data structure. I'm trying to exploit boost::multi_index::sequenced<> to shadow the vector offset, and provide a mechanism for richer data queries. I really don't want to unnecessarily copy all the data from one container to another.
In the example code snippet below I have a class BarInterface that manages the insertion and removal of elements to the Bar::foos container. Initially I tried to store references to the vector elements as elements of the typedef boost::multi_index_container, but these are not stable against insertions.
What I'd like to do is have a custom key extractor that is a function of the _bar container and the boost::multi_index::sequenced<> index. So, for example to get the name of an element, I'd find the sequence offset x, and then _bar.foos[x].name. So, I'm really just using boost::multi_index as a proxy for richer queries against a vector of variable size.
struct Foo {
std::string name;
};
struct Bar {
std::vector<Foo> foos;
};
class BarInterface {
public:
struct Dummy {};
BarInterface(Bar& bar) : _bar(bar) {
for (auto& foo : bar.foos) {
_idx.get<1>().insert(Dummy{});
}
}
// Index
struct Name {};
typedef boost::multi_index_container<
Dummy, // We're not actually storing anything here
boost::multi_index::indexed_by<
boost::multi_index::sequenced<>, // Kept inline with vector order!
boost::multi_index::ordered_unique<
boost::multi_index::tag<Name>,
// I need something here that takes the boost::multi_index::sequenced<>
// key to get the offset x, and then returns this->_bar.foos[x].name!
>
>
> MultiIndex;
// Insert
void insert(const Foo& foo) {
_bar.foos.push_back(foo);
_idx.get<1>().insert(Dummy{});
}
// Remove
template <typename T>
void remove(T it) {
_bar.foos.erase(_bar.foos.begin() + std::distance(_idx.begin(), _idx.project<0>(it)));
_idx.erase(_idx.project<0>(it));
}
protected:
Bar& _bar;
MultiIndex _idx;
};
I know that boost::multi_index supports all sorts of key extractors -- for member variables, member functions, global function, etc. However, I can't seem to find an example showing how to generate a key as a function of a boost::multi_index::sequenced<> index. Is this possible, or is there an elegant alternative?
This is extremely brittle and I wouldn't recommend going to production with such code, but since you asked for it:
Live Coliru Demo
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <iostream>
#include <string>
#include <vector>
struct Foo {
std::string name;
};
struct Bar {
std::vector<Foo> foos;
};
class BarInterface;
struct Dummy
{
Dummy(const Foo& x): p(&x){}
Dummy(const Dummy&): p(nullptr){}
const Foo* p;
};
struct NameExtractor
{
NameExtractor(BarInterface* p): p(p){}
using result_type=std::string;
const result_type& operator()(const Dummy& d)const;
BarInterface* p;
};
class BarInterface {
public:
BarInterface(Bar& bar) :
_idx(boost::make_tuple(
boost::tuple<>(),
boost::make_tuple(NameExtractor(this), std::less<std::string>())
)),
_bar(bar)
{
for (auto& foo : bar.foos) {
_idx.get<1>().insert(bar.foos.back());
}
}
// Index
struct Name {};
typedef boost::multi_index_container<
Dummy, // We're not actually storing anything here
boost::multi_index::indexed_by<
boost::multi_index::random_access<>, // Kept inline with vector order!
boost::multi_index::ordered_unique<
boost::multi_index::tag<Name>,
NameExtractor
>
>
> MultiIndex;
// Insert
void insert(const Foo& foo) {
_bar.foos.push_back(foo);
_idx.get<1>().insert(_bar.foos.back());
}
// Remove
template <typename T>
void remove(T it) {
_bar.foos.erase(_bar.foos.begin() + std::distance(_idx.begin(), _idx.project<0>(it)));
_idx.erase(_idx.project<0>(it));
}
void remove(const char* name) {
remove(_idx.get<1>().find(name));
}
void print()const
{
auto key=_idx.get<1>().key_extractor();
for(const auto& d: _idx.get<1>()){
std::cout<<key(d)<<" ";
}
std::cout<<"\n";
}
protected:
friend NameExtractor;
Bar& _bar;
MultiIndex _idx;
};
const NameExtractor::result_type& NameExtractor::operator()(const Dummy& d)const
{
if(d.p){
return d.p->name;
}
else{
std::size_t offset=p->_idx.iterator_to(d)-p->_idx.begin();
return p->_bar.foos[offset].name;
}
}
int main()
{
Bar bar;
BarInterface bi(bar);
bi.insert(Foo{"hello"});
bi.insert(Foo{"bye"});
bi.insert(Foo{"Boost"});
bi.print();
bi.remove("bye");
bi.print();
bi.insert(Foo{"MultiIndex"});
bi.print();
}
Output
Boost bye hello
Boost hello
Boost MultiIndex hello
I have a template class, and at least 95% codes of it is same for all types of the template-parameter, unless a member-variable and a function should be added for one specialization.
The sample I want to get is following:
template <typename T>
class AClass {
private:
T payLoad;
public:
AClass( const T& crp_payload ) : payLoad( crp_payload ) {};
void showMe() {
cout << "Common showMe:" << payLoad << endl;
};
/*
* A lot of functions same for all specializations go here.
* I absolutely don't want to implement respectively them for
* every specializations!
*/
// specializing for int ----------------------------
// dedicated function
template <int>
void showPayload() {
cout << "AClass<int>::showPayload:" << payLoad << endl;
};
// dedicated variable, but following code can not be compiled!
template <int>
int otherPayload;
};
int main() {
AClass<int> iac( 123 );
iac.showMe();
iac.showPayload();//can not pass the compiling!
AClass<float> fac(456);
fac.showMe();
return 0;
};
My questions:
How to add merely "otherPayload" variable without re-coding entire
AClass<int>?
How to call showPayload() sinc I get a error msg when I
do it in main() as above.
Is there no way only by specializing to "revise/supplement" some
members to a class without totally re-implement it?
One possible way would be the good old inheritance:
template<class T> struct Extra {};
template<> struct Extra<int> {
int extraPayload;
void showPayload();
};
template<class T> class Class: public Extra<T> {
void showMe();
};
template<> void Class<int>::showMe() { showPayload(); }
All the specialization-specific parts are extracted in a separate class, and common methods are specialized as needed.
I think you can simply do normal specialization of the template-class:
#include <iostream>
#include <iomanip>
template <typename T>
class BaseClass
{
protected:
T payLoad;
public:
BaseClass(const T& crp_payload)
: payLoad( crp_payload )
{ }
void showMe() {
std::cout << "Common showMe:" << payLoad << std::endl;
}
/*
* A lot of functions same for all specializations go here.
* I absolutely don't want to implement respectively them for
* every specializations!
*/
};
template <typename T>
class AClass
: public BaseClass<T>
{
public:
AClass( const T& crp_payload )
: BaseClass<T>(crp_payload)
{ }
};
// specializing for int ----------------------------
template<>
class AClass<int>
: public BaseClass<int>
{
public:
AClass( int crp_payload )
: BaseClass(crp_payload)
{ }
// dedicated function
void showPayload() {
std::cout << "AClass<int>::showPayload:" << payLoad << std::endl;
}
private:
int otherPayload;
};
int main() {
AClass<int> iac( 123 );
iac.showMe();
iac.showPayload();//can not pass the compiling!
AClass<float> fac(456);
fac.showMe();
return 0;
}
I'm trying to store and manipulate a list of template class objects with different parameter types; the template class has two parametrised methods, one returning the parameter type and a void one accepting it as input.
More specifically, I have a template class defined as follows:
template<typename T>
class Test
{
public:
virtual T a() = 0;
virtual void b(T t) = 0;
};
And different specifications of it, such as:
class TestInt : public Test<int>
{
public:
int a() {
return 1;
}
void b(int t) {
std::cout << t << std::endl;
}
};
class TestString : public Test<std::string>
{
public:
std::string a() {
return "test";
}
void b(std::string t) {
std::cout << t << std::endl;
}
};
I'd like to be able to store in one single list different objects of both TestInt and TestString type and loop through it calling one method as input for the other, as in:
for (auto it = list.begin(); it != list.end(); ++it)
(*it)->b((*it)->a());
I've looked into boost::any but I'm unable to cast the iterator to the specific class, because I don't know the specific parameter type of each stored object. Maybe this cannot be done in a statically typed language as C++, but I was wondering whether there could be a way around it.
Just for the sake of completeness, I'll add that my overall aim is to develop a "parametrised observer", namely being able to define an observer (as with the Observer Pattern) with different parameters: the Test class is the observer class, while the list of different types of observers that I'm trying to properly define is stored within the subject class, which notifies them all through the two methods a() and b().
The virtuals have actually no meaning here, since for each T the signatures are distinct.
So it seems you have Yet Another version of the eternal "how can we emulate virtual functions templates" or "how to create an interface without virtual functions":
Generating an interface without virtual functions?
How to achieve "virtual template function" in C++
The first one basically contains an idea that you could employ here.
Here's an idea of what I'd do:
Live On Coliru
#include <algorithm>
#include <iostream>
namespace mytypes {
template <typename T>
struct Test {
T a() const;
void b(T t) { std::cout << t << std::endl; }
};
template <> int Test<int>::a() const { return 1; }
template <> std::string Test<std::string>::a() const { return "test"; }
using TestInt = Test<int>;
using TestString = Test<std::string>;
}
#include <boost/variant.hpp>
namespace mytypes {
using Value = boost::variant<int, std::string>;
namespace detail {
struct a_f : boost::static_visitor<Value> {
template <typename T>
Value operator()(Test<T> const& o) const { return o.a(); }
};
struct b_f : boost::static_visitor<> {
template <typename T>
void operator()(Test<T>& o, T const& v) const { o.b(v); }
template <typename T, typename V>
void operator()(Test<T>&, V const&) const {
throw std::runtime_error(std::string("type mismatch: ") + __PRETTY_FUNCTION__);
}
};
}
template <typename O>
Value a(O const& obj) {
return boost::apply_visitor(detail::a_f{}, obj);
}
template <typename O, typename V>
void b(O& obj, V const& v) {
boost::apply_visitor(detail::b_f{}, obj, v);
}
}
#include <vector>
int main()
{
using namespace mytypes;
using AnyTest = boost::variant<TestInt, TestString>;
std::vector<AnyTest> list{TestInt(), TestString(), TestInt(), TestString()};
for (auto it = list.begin(); it != list.end(); ++it)
b(*it, a(*it));
}
This prints
1
test
1
test
Bonus Points
If you insist, you can wrap the AnyTest variant into a proper class and have a() and b(...) member functions on that:
Live On Coliru
int main()
{
using namespace mytypes;
std::vector<AnyTest> list{AnyTest(TestInt()), AnyTest(TestString()), AnyTest(TestInt()), AnyTest(TestString())};
for (auto it = list.begin(); it != list.end(); ++it)
it->b(it->a());
}
Expanding on my comment above, the simplest what I can currently think of to achieve what you are trying to do - at least as I understood it from your example code - is the following:
/* Interface for your container, better not forget the destructor! */
struct Test {
virtual void operate(void) = 0;
virtual ~Test() {}
};
/* Implementation hiding actual type */
template<typename T>
struct TestImpl : public T, public Test {
void operate(void) {
T::b(T::a());
}
};
/* Actual code as template policies */
struct IntTest {
int a(void) {
return 42;
}
void b(int value) {
std::cout << value << std::endl;
}
};
struct StringTest {
std::string a(void) {
return "Life? Don't talk to me about life.";
}
void b(std::string value) {
std::cout << value << std::endl;
}
};
You would then need to create a container for objects of class Test and fill it with objects of the respective TestImpl<IntTest>, TestImpl<StringTest>, and so on. To avoid object slicing you need reference or pointer semantics, that is std::vector<std::unique_ptr<Test> > for example.
for (auto it = list.begin(); it != list.end(); ++it) {
(*it)->operate();
}
I have written a small piece of code where I am able to call setter and getter functions packed within a functoid using mem_fun templates.
I now would like to use this approach on top of a class hierarchy where every class might have getter and setter which can be registered as pair within a vector or array to be able to call the getter and setter if needed. GUIObject and GUICompositeObject are example classes out of the described class hierarchy.
The bound_mem_fun_t for the objects have unfortunately different types and thats the reason I don't know how to integrate them into an array/vector of pointers to the functors.
In c++11 I would use std::function. Is there a way to emulate this in c++98?
Because our compiler support only c++98 I cannot use the new features of c++11 or c++14. Also boost is not allowed.
#include <functional>
class GUIObject
{
int m_Alpha;
public:
void SetAlpha(int a) { m_Alpha = a;};
int GetAlpha() {return m_Alpha;};
};
class GUICompositeObject: public GUIObject
{
int m_NumOfChilds;
public:
void SetNumOfChilds(int NumOfChilds) { m_NumOfChilds = NumOfChilds;};
int GetNumOfChilds() {return m_NumOfChilds;};
};
template<typename T>
struct bound_mem_fun_t
{
bound_mem_fun_t(std::mem_fun_t<int, T> GetFunc, std::mem_fun1_t<void, T, int> SetFunc, T* o) :
m_GetFunc(GetFunc), m_SetFunc(SetFunc), obj(o) { } ;
int operator()() { return m_GetFunc(obj); } ;
void operator()(int i) { m_SetFunc(obj, i); } ;
std::mem_fun_t<int, T> m_GetFunc;
std::mem_fun1_t<void, T, int> m_SetFunc;
T* obj;
};
int main()
{
GUIObject kGUIObject;
GUICompositeObject kCompObj;
bound_mem_fun_t<GUIObject> GUIObjectFunc(std::mem_fun(&GUIObject::GetAlpha), std::mem_fun(&GUIObject::SetAlpha), &kGUIObject);
GUIObjectFunc(17);
int ii = GUIObjectFunc();
bound_mem_fun_t<GUICompositeObject> GUICompObjectFunc(std::mem_fun(&GUICompositeObject::GetNumOfChilds), std::mem_fun(&GUICompositeObject::SetNumOfChilds), &kCompObj);
GUICompObjectFunc(17);
int iChilds = GUICompObjectFunc();
return 0;
}
Here is the complete solution after #filmors answer:
#include <functional>
#include <vector>
#include <iostream>
class GUIObject
{
int m_Alpha;
public:
void SetAlpha(int a) { m_Alpha = a;};
int GetAlpha() {return m_Alpha;};
};
class GUICompositeObject: public GUIObject
{
int m_NumOfChilds;
public:
void SetNumOfChilds(int NumOfChilds) { m_NumOfChilds = NumOfChilds;};
int GetNumOfChilds() {return m_NumOfChilds;};
};
struct bound_mem_fun_base
{
virtual int operator()() =0;
virtual void operator()(int) =0;
};
template<typename T>
struct bound_mem_fun_t : public bound_mem_fun_base
{
bound_mem_fun_t(std::mem_fun_t<int, T> GetFunc, std::mem_fun1_t<void, T, int> SetFunc, T* o) :
m_GetFunc(GetFunc), m_SetFunc(SetFunc), obj(o) { } ;
virtual int operator()() { return m_GetFunc(obj); } ;
virtual void operator()(int i) { m_SetFunc(obj, i); } ;
std::mem_fun_t<int, T> m_GetFunc;
std::mem_fun1_t<void, T, int> m_SetFunc;
T* obj;
};
template<typename T> bound_mem_fun_t<T>* make_setter(std::mem_fun_t<int, T> GetFunc, std::mem_fun1_t<void, T, int> SetFunc, T* o)
{
return new bound_mem_fun_t<T> (GetFunc, SetFunc, o);
}
int main()
{
GUIObject kGUIObject;
GUICompositeObject kCompObj;
std::vector<bound_mem_fun_base*> kBoundVector;
kBoundVector.push_back(new bound_mem_fun_t<GUIObject> (std::mem_fun(&GUIObject::GetAlpha), std::mem_fun(&GUIObject::SetAlpha), &kGUIObject));
kBoundVector.push_back(new bound_mem_fun_t<GUICompositeObject> (std::mem_fun(&GUICompositeObject::GetNumOfChilds), std::mem_fun(&GUICompositeObject::SetNumOfChilds), &kCompObj));
kBoundVector.push_back(make_setter<GUIObject> (std::mem_fun(&GUIObject::GetAlpha), std::mem_fun(&GUIObject::SetAlpha), &kGUIObject));
kBoundVector.push_back(make_setter<GUICompositeObject> (std::mem_fun(&GUICompositeObject::GetNumOfChilds), std::mem_fun(&GUICompositeObject::SetNumOfChilds), &kCompObj));
for (int i = 0; i < 4 ; i++)
{
(*kBoundVector[i])(i*10);
int res = (*kBoundVector[i])();
std::cout << "Getter result " << res << "\n";
}
return 0;
}
Unfortunately the make_setter function does not really shorten the creation of the functor. Any ideas will be welcome.
Just give your bound_mem_fun_t<T> a common base class and use dynamic dispatch to solve your problem:
struct bound_mem_fun_base {
virtual int operator()() = 0;
virtual void operator()(int) = 0;
};
template <typename T>
struct bound_mem_fun_t : bound_mem_fun_t ...
Then you can keep pointers to bound_mem_fun_base in your vector and call the elements as (*v[0])().
Also, TR1 does contain std::tr1::function, is that available?
First a remark on std::function from c++11: That will not solve your problem, because you need an already bounded function pointer. This pointer must be bound to your object. I believe what you need is an own implementation to std::bind.
I started only a very! small Binder class which is hopefully a starting point for your needs. If you need to have template parameter lists in older c++ versions, take a look for loki. http://loki-lib.sourceforge.net/
As a hint I can give you a short example of what i did:
class A
{
private:
int val;
public:
A(int i): val(i) {}
void Do(int i) { std::cout << "A " << val<< " " << i << std::endl; }
};
class B
{
private:
int val;
public:
B(int i): val(i){}
void Go(int i) { std::cout << "B " << val << " " << i << std::endl; }
};
class Base
{
public:
virtual void operator()(int i)=0;
};
template <typename T>
class Binder: public Base
{
void (T::*fnct)(int);
T* obj;
public:
Binder( void(T::*_fnct)(int), T*_obj):fnct(_fnct),obj(_obj){}
void operator()(int i)
{
(obj->*fnct)(i);
}
};
int main()
{
A a(100);
B b(200);
// c++11 usage for this example
//std::function<void(int)> af= std::bind( &A::Do, &a, std::placeholders::_1);
//af(1);
// hand crafted solution
Base* actions[2];
actions[0]= new Binder<A>( &A::Do, &a);
actions[1]= new Binder<B>( &B::Go, &b);
actions[0]->operator()(55);
actions[1]->operator()(77);
}