Simply put, if I have a set and vector how do I create a generic method that can handle both as params.
All I want to do, is iterate over either types of collections. Sounds like it should be trivial but I'm missing something.
void printMeSomeStrings(somebaseclass<string> strings) {
for (auto& str : strings) {
cout << str << endl;
}
}
In C#, I would pass IEnumerable or something like that. Then I could iterate over the collection.
Any general reading explaining the answer would be appreciated.
You could use templates. For instance:
#include <iostream>
template<typename C>
void foo(C const& c)
{
std::cout << "{ ";
for (auto const& x : c)
{
std::cout << x << " ";
}
std::cout << "}";
}
And here is how you would use it:
#include <set>
#include <vector>
int main()
{
std::vector<int> v = {1, 2, 3};
foo(v);
std::cout << std::endl;
std::set<std::string> s = {"Hello,", "Generic", "World!"};
foo(s);
}
Live example.
This is exactly what iterators were designed for.
template <class It>
void print_some_strings(It first, It last) {
while (first != last)
std::cout << *first++ << '\n';
}
The first option is to put the code doing the iterating in a template. This requires exposing the implementation to everyone who uses it, which has disadvantages.
Basically, take a type C as a template parameter, then write your code in terms of that type C.
template<typename C>
void printMeSomeStrings(C&& strings) {
for (auto const& str : strings) {
cout << str << endl;
}
}
If you want to be able to have a strong barrier between interface and implementation, the C++11 approach would be to engage in type erasure on a for-iterable container, and then expose a for-iterable container, like how std::function works.
This is trickier. I personally find writing a for_each function easier than writing a full blown iteration adapter. If you want the full blown container iteration type erasure object, start with boost, or ask me below and I might do it.
The for_each adaptor is easy, however.
#include <functional>
#include <utility>
#include <iterator>
#include <memory>
template<typename T>
struct for_each_helper_interface {
virtual ~for_each_helper_interface() {}
virtual void for_each( std::function< void(T) > const& ) = 0;
};
template<typename C, typename T>
struct for_each_helper:for_each_helper_interface<T> {
C& c;
for_each_helper( C& in ):c(in) {}
virtual void for_each( std::function< void(T) > const& f ) override final {
for( auto&& x:c ) {
f(x);
}
}
};
template<typename T>
struct for_each_adaptor {
std::unique_ptr<for_each_helper_interface<T>> pImpl;
void for_each( std::function< void(T) > const& f ) {
if (pImpl) {
pImpl->for_each(f);
}
}
template<typename C>
for_each_adaptor( C&& c ): pImpl( new for_each_helper<C, T>( std::forward<C>(c) ) ) {}
};
which will type-erase the container of T (or a type convertible to T!) and expose a for_each method that lets you iterate over the contents of the container. Use like this:
#include <set>
#include <iostream>
#include <vector>
void print_stufF( for_each_adaptor<std::string const&> c ) {
c.for_each([&](std::string const&s){
std::cout << s << "\n";
});
}
int main() {
std::set<std::string> s;
s.insert("hello");
s.insert("world");
print_stuff(s);
std::vector<std::string> v;
v.push_back("hola");
v.push_back("bola");
print_stuff(v);
}
What is going on here is that for each type used to construct our adaptor, we build a custom implementation of for each. We then store a pointer to the abstract base class of this custom class, and redirect for each calls to it.
This means anything that specializes std::begin or defines its own begin need not be related: we create ad hoc relationships at point of use instead.
Live example: http://ideone.com/xOqBkI
In C#, I would pass IEnumerable or something like that.
C++ uses the more pythonic approach of duck typing to define interfaces(generally called a concept in C++), rather than using inheritance. To do duck typing in C++, you use a template function like this:
template<typename C>
void printMeSomeStrings(const C& strings)
{
for (const auto& str : strings)
{
cout << str << endl;
}
}
In python, duck typing is done at runtime, but in C++ it is done at compile time, so there is no runtime cost to duck typing, and everything is checked at compile time as well.
Here is more info about C++, to help with looking for information. First, the equivalent of the IEnumerator<T> is the iterator in C++. Here is a page about the different iterator categories, and what needs to be implemented for iterators. For legacy reasons, iterators are modeled after pointers in C, which lets you use C arrays with the standard C++ algorithms.
However, unlike IEnumerator<T>, iterators must come in pairs. An iterator to the begining and the end(which is one past the last element). So, the equivalent of IEnumerable<T> in C++ is called a range. In C++11, a range is defined by two free functions, begin(T) and end(T)(it can also be implemented as member function .begin() and .end()).
By defining the concept(aka interface) as two free function, as opposed to using inheritance, ranges can be implemented non-intrusively. So for example, if you have work with some legacy api that uses C style linked lists. They can now be adapted as a C++11 range and used inside a C++ for loop.
Related
I have a function that takes a T and calls specific functions on the supplied object. Until now it was used from compile-time objects, so all was great. Minimal example:
#include <iostream>
struct A {
void fun() const { std::cout << "A" << std::endl; }
};
struct B {
void fun() const { std::cout << "B" << std::endl; }
};
template<class T>
void use_function(const T& param) {
param.fun();
}
int main() {
use_function(A{}); // "A"
use_function(B{}); // "B"
return 0;
}
Now I'm trying to use that use_function() with objects that get created at runtime and having a hard time. I can't use std::variant or std::any since I need to supply the type as template parameter for their access functions - although all their variants fulfil the function interface. Example for a (failing) variant approach:
using var_type = std::variant<A, B>;
struct IdentityVisitor {
template<class T>
auto operator()(const T& alternative) const -> T {
return alternative;
}
};
int main() {
var_type var = A{};
// error C2338: visit() requires the result of all potential invocations to have the same type and value category (N4828 [variant.visit]/2).
use_function(std::visit(IdentityVisitor{}, var));
return 0;
}
What is possible is directly calling the function with an appropriate type like this:
if (rand() % 2 == 0)
use_function(A{});
else
use_function(B{});
just storing it in between is what I can't get working.
I understand on a technical level but having trouble coming up with an elegant solution. Is there one? I know that I could rewrite the objects with even a lightweight inheritance - but was trying to see if it's feasible to avoid it altogether, even if just as an exercise to avoid OOP in favor of templates and concepts. I feel like variants should be working with this, but apparently not.
std::visit([](auto const& x) { use_function(x); }, var);
If overload sets were objects, you could pass use_function to std::visit directly. Because they aren't, you need to wrap it in something that will be instantiated as a call to the right overload.
std::visit([](auto const& x) { use_function(x); }, var);
I'm trying to create C# event in c++ for my game engine. I'm implementing the event system now but I don't know how to remove a std::function in a vector. Am I using the correct list?
I'm quite new in C++ but I'm a C# programmer for 10 years now. Is this possible in C++?
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
struct Delegate {
std::vector<std::function<void()>> funcs;
template<class T> void operator+=(T mFunc)
{
funcs.push_back(mFunc);
}
template<class T> void operator-=(T mFunc)
{
// How?
//funcs.erase(std::remove(funcs.begin(), funcs.end(), mFunc), funcs.end());
}
void operator()() {
for (auto& f : funcs) f();
}
};
void fun1()
{
std::cout << "hello, ";
}
void fun2()
{
std::cout << "Delete";
}
void fun3()
{
std::cout << "world!" << std::endl;
}
int main() {
Delegate delegate;
delegate += fun1;
delegate += fun2;
delegate -= fun2;
delegate += fun3;
delegate();
}
If you are willing to limit Delegate to only using function pointers the you can do it with what you have. That would look like
struct Delegate {
std::vector<void(*)()> funcs;
template<class T> void operator+=(T mFunc)
{
funcs.push_back(mFunc);
}
template<class T> void operator-=(T mFunc)
{
funcs.erase(std::remove(funcs.begin(), funcs.end(), mFunc), funcs.end());
}
void operator()() {
for (auto& f : funcs) f();
}
};
If you don't want to do so, then you need to change you approach. You could have operator += return an index to the inserted function, and then you can change operator -= to take that index and remove that element. see eerorika's answer for a suggestion on how to return iterators to the functions.
Is this possible in C++?
Not like this. Function wrappers cannot be compared for equality. This is a limitation in their design.
One option is to use function pointers. They can be compared for equality. But then you cannot use stateful function objects. NathanOliver shows an example of this.
Another alternative design would be to use a std::list as the container, and when ever you register a function, return iterator to it. Then, instead of erasing by passing the function, you can pass the iterator to be erased.
std::function objects are not directly comparable, but if you are only using regular functions (not e.g. member functions or capturing lambdas), you can use target() method to extract underlying pointer.
void operator-=(void(*mFunc)())
{
auto pred = [&mFunc](const std::function<void()>& func) { return mFunc == *func.target<decltype(mFunc)>(); };
funcs.erase(std::remove_if(funcs.begin(), funcs.end(), pred), funcs.end());
}
I changed the type T to be function pointer explicitly, because std::function would need a different approach (calling target() on that too). You can overload your operator -= to handle std::function separately.
It's ugly, but it works.
Note: Above snippet doesn't really take into account type safety. target() will return nullptr if type declared by template does not match the actual type stored by std::function, and dereferencing nullptr will be disastrous. Since your code only seems to deal with free functions of signature void(), it shouldn't be much issue, but if you plan to use lambdas or something it may break.
Are we supposed to be able to inherit from Qt containers such as QList, QVector or QMap in order to specialize them and add functionality? If so, what do we need to do in order to be sure that the container works correctly (virtual methods, virtual destructor etc..?). If not, why not and what other options do I have?
Both, STL and Qt Containers opt for non virtual destructors.
There is an interesting discussion why this is, and why its not fixed with Qt5.
QList has no virtual destructor, but is inherited from http://qt-project.org/forums/viewthread/16416
Also, note further differences between STL style and Qt containers. Quoting Jens Weller in his Blog post An introduction into Qt:
Still, there is an important difference between Qt containers and STL containers: Qt containers have value semantics, and will only perform copy on write, while a std container will copy its full contents when copied. This behavoir accounts for most of Qt base classes, that they will only create a new instance for data, when needed. This implicit sharing of resources is a very important concept to understand when dealing with Qt and its containers.
Your options are as always:
composition
E.g.
struct MyFancyList
{
QList<MyType> _data;
bool frobnicate() { return true; }
};
free functions
E.g. extend QList with non-member operations:
template <typename> bool frobnicate(QList<T>& list)
{
// your algorithm
return true;
}
If you really wanted to do funcky stuff, like create an implicit conversion or overload a member operator, you could resort to expression templates.
Update: the latter is also the approach taken by QStringBuilder in new versions. See
Lecture: Expression Templates (video, slides) by Volker Krause
Bonus
For fun, here's a (bad!) illustration of how you could use expression templates to extend the interface of std::stack<T>. See it Live on Coliru or ideone
As we all know, std::stack doesn't model a sequential container, and therefore doesn't have begin(), end(), or operator[] defined. With a bit of hackery, we can define a eDSL to provide these features, without composition or inheritance.
To really drive the point home that you can 'overload' behaviour of the wrapped class in essential ways, we'll make it so that you can implicitly convert the result of extend(stack)[n] to a std::string, even if the stack contains e.g. int.
#include <string>
#include <stack>
#include <stdexcept>
namespace exprtemplates
{
template <typename T> struct stack_indexer_expr
{
typedef std::stack<T> S;
S& s;
std::size_t n;
stack_indexer_expr(S& s, std::size_t n) : s(s), n(n) {}
operator T() const {
auto i = s.size()-n; // reverse index
for (auto clone = s; !clone.empty(); clone.pop())
if (0 == --i) return clone.top();
throw std::range_error("index out of bounds in stack_indexer_expr");
}
operator std::string() const {
// TODO use `boost::lexical_cast` to allow wider range of T
return std::to_string(this->operator T());
}
};
template <typename T> struct stack_expr
{
typedef std::stack<T> S;
S& s;
stack_expr(S& s) : s(s) {}
stack_indexer_expr<T> operator[](std::size_t n) const {
return { s, n };
}
};
}
Now all we have to do is seed our expression templates. We'll use a helper function that wraps any std::stack:
template <typename T>
exprtemplates::stack_expr<T> extend(std::stack<T>& s) { return { s }; }
Ideally, our users never realize the exact types inside exprtemplates namespace:
#include <iostream>
int main()
{
std::stack<double> s;
s.push(0.5);
s.push(0.6);
s.push(0.7);
s.push(0.8);
std::string demo = extend(s)[3];
std::cout << demo << "\n";
}
Voila. More craziness:
auto magic = extend(s);
std::cout << magic[0] << "\n";
std::cout << magic[1] << "\n";
std::cout << magic[2] << "\n";
std::cout << magic[3] << "\n";
double as_double = magic[0];
std::string as_string = magic[0];
Prints
0.5
0.6
0.7
0.8
DISCLAIMERS
I know std::stack has a restrictive interface for a reason.
I know that my indexing implementation has horrific efficiency.
I know that implicit conversions are evil. This is just a contrived example.
In real life, use Boost::Proto to get a DSL going. There are many pitfalls and gotchas in doing all the mechanics by hand.
Look at QStringBuilder for a more real life sample.
I have multiple controls organized like this:
deque<wxTextCtrl*> dequeEdit;
deque<wxStaticText*> dequeText;
deque<wxComboBox*> dequeCombo;
All these controls inherit from wxWindow which has mathod Show. I'd like to show (or hide) whole deque at once, without the need of multiple methods for each deque. How could it be done?
I was thinking about making deque of wxWindow for each control, so I could write method
ShowDeque(deque<wxWindow*> deque)
so showing would be easy, but on the other hand, if I'd like to work with e.g. combobox, I'd have to type it back to wxComboBox.
Are there any other possibilites? Thanks.
Use:
for_each(dequeEdit.begin(), dequeEdit.end(), mem_fun(&wxWindow::Show));
Same for any other deques.
Or encapsulate in one function:
template <class Deque>
void showAll(const Deque& dequeObj)
{
using namespace std;
for_each(dequeObj.begin(), dequeObj.end(), mem_fun(&wxWindow::Show));
}
showAll(dequeEdit);
std::for_each: http://en.cppreference.com/w/cpp/algorithm/for_each
std::mem_fun: http://en.cppreference.com/w/cpp/utility/functional/mem_fn
If it's a simple method make it a template:
template <typename WxT>
void ShowDeque(std::deque<WxT*> &d) { ... }
or better, use iterators to abstract out the container type:
template <typename WxIter>
void ShowDeque(WxIter begin, WxIter end) { ... }
or better yet use the standard facilities (Piotr beat me to that one while I was typing!)
You can use a function template.
template <typename T>
void show_all(const std::deque<T*>& d) {
for (typename std::deque<T*>::iterator it=d.begin(); it!=d.end(); ++it)
(*it)->Show();
}
You can then call it like a normal function.
deque<wxTextCtrl*> dequeEdit;
deque<wxStaticText*> dequeText;
deque<wxComboBox*> dequeCombo;
show_all(dequeEdit);
show_all(dequeText);
show_all(dequeCombo);
With a function template you can even make show_all independent of the container you use by adding an additional template argument.
template <typename C, typename T>
void show_all(const C<T*>& d) {
for (typename C<T*>::iterator it=d.begin(); it!=d.end(); ++it)
(*it)->Show();
}
C can then be any STL container, or even any container which supports the same iterator interface.
I came across this question when looking for how to use inheritance of iterators and deque.
The answer's does not give a complete answer related to inheritance, so I will add following:
Let say you have a class and you want this class to have the ability to have a deque inside, in other words to inherit the ability to control a deque container.
Example :
template<typename ElementType>
class myQueOfElements : public deque<ElementType>
{
ElementType placeholder;
myQueOfElements& operator=(unsigned char* rvalue)
{
unsigned char* ptrToNextElement = (unsigned char*)rvalue;
placeholder = ptrToNextElement; // make sure ElementType has its own assignment operator=
push_back(placeholder); // First element
//TODO: Iterate thru the binary and push_back the fetched elements
return *this;
}
};
// How to use:
myQueOfElements<myElementTypeClass> testQue;
testQue = (unsigned char*)&blob[0]; // address to binary data, will be parsed in the assignment operator=
// make sure it has same structure as the ElementType (myElementTypeClass)
// fetch all myElementTypeClass object(s) from the myQueOfElements
for (auto e : testQue) {
std::string strName = e.Name;
std::out << "Element : " << strName.c_str() << endl;
}
I have a class that uses several policies that are templated. It is called Dish in the following example. I store many of these Dishes in a vector (using a pointer to simple base class), but then I'd like to extract and use them. But I don't know their exact types.
Here is the code; it's a bit long, but really simple:
#include <iostream>
#include <vector>
struct DishBase {
int id;
DishBase(int i) : id(i) {}
};
std::ostream& operator<<(std::ostream& out, const DishBase& d) {
out << d.id;
return out;
}
// Policy-based class:
template<class Appetizer, class Main, class Dessert>
class Dish : public DishBase {
Appetizer appetizer_;
Main main_;
Dessert dessert_;
public:
Dish(int id) : DishBase(id) {}
const Appetizer& get_appetizer() { return appetizer_; }
const Main& get_main() { return main_; }
const Dessert& get_dessert() { return dessert_; }
};
struct Storage {
typedef DishBase* value_type;
typedef std::vector<value_type> Container;
typedef Container::const_iterator const_iterator;
Container container;
Storage() {
container.push_back(new Dish<int,double,float>(0));
container.push_back(new Dish<double,int,double>(1));
container.push_back(new Dish<int,int,int>(2));
}
~Storage() {
// delete objects
}
const_iterator begin() { return container.begin(); }
const_iterator end() { return container.end(); }
};
int main() {
Storage s;
for(Storage::const_iterator it = s.begin(); it != s.end(); ++it){
std::cout << **it << std::endl;
std::cout << "Dessert: " << *it->get_dessert() << std::endl; // ??
}
return 0;
}
The tricky part is here, in the main() function:
std::cout << "Dessert: " << *it->get_dessert() << std::endl; // ??
How can I access the dessert? I don't even know the Dessert type (it is templated), let alone the complete type of the object that I'm getting from the storage.
This is just a toy example, but I think my code reduces to this. I'd just like to pass those Dish classes around, and different parts of the code will access different parts of it (in the example: its appetizer, main dish, or dessert).
What you have is not exactly policy-based design IMO... if it were, your class should've actually implemented (i.e. extended) the policies.
Now, back to your question/example. In your container, you store a "DishBase*". Right? From that point on, you loose any compile-time information wrt the actual type of the objects in the collection. So, I'm afraid what you try to do is provably impossible.
What you could do, is use an actual policy-based design, eg.
template<class Appetizer, class Main, class Dessert>
class Dish : public DishBase, Appetizer, Main, Dessert {
}
Then, you could simply use dynamic_cast to check at runtime that you can convert your object to any concrete Appetizer/Dessert/Main.
But from your description, I get the impression that you actually need abstract base classes (i.e. abstract base classes may be the design that makes sense for you, and not policies).
You will need to have appropriate member functions for querying (in this case an overload for the concrete Dessert type). The policies should expose a way of discovery. Here's a short example:
#include <iostream>
using namespace std;
struct TA { virtual string foo() { return "TA::foo\n"; } };
struct DTA : TA { virtual string foo() { return "DTA::foo\n"; } };
template <class T>
struct C {
T t;
};
template <class T>
ostream& operator <<(ostream& o, C<T> c) {
o << c.t.foo();
return o;
}
int main(int argc, char* argv[])
{
C<DTA> c;
cout << c;
}
My understanding is that policy-based template classes are not very container friendly. I just opt for plain old polymorphism for this kind of things. I'd be interested in a solution though.
EDIT: It's perhaps not by coincidence that I cannot find any usage of stl containers throughout Alexandrescu's "Modern C++ Desing" book.
EDIT2: More details on the friction between polymorphism and genericity can be found here http://www.artima.com/cppsource/type_erasure.html. You container can perhaps be made of boost::any objects?