8
\$\begingroup\$

I made a template pipe and filters to replace an old pipe and filters implementation that used inheritance and had a very heavy base class.

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <list>
template <typename Data>
class pipeline {
 typedef boost::function<Data(Data)> filter_function;
 typedef std::list<filter_function> filter_list;
 filter_list m_list;
public:
 template<typename T>
 void add(T t) {
 m_list.push_back(boost::bind(&T::filter, t, _1));
 }
 Data run(Data data) {
 typedef typename filter_list::iterator iter;
 iter end = m_list.end();
 for(iter it = m_list.begin(); it != end; ++it) {
 data = (*it)(data);
 }
 return data;
 }
};
struct foo {
 int filter(int i) {
 return i + 1;
 }
};
int main(int argc, _TCHAR* argv[])
{
 pipeline<int> pipe;
 foo f;
 pipe.add(f);
 std::cout << pipe.run(0);
 char c;
 std::cin >> c;
}

Except the fact that add() is a template, are there any issues anyone sees with this approach?

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked May 21, 2013 at 16:50
\$\endgroup\$
1
  • \$\begingroup\$ The answers really depend on what C++ standard you have access to. With C++11, you could throw boost away. \$\endgroup\$ Commented Apr 22, 2017 at 12:20

2 Answers 2

7
\$\begingroup\$
  • As run() is several lines long, it should be defined outside the class. Anything defined inside is automatically inlined.

  • Depending on the size of data when passing by value, it may be best to pass it to run() by const&, modify a local copy, and return that. RVO should still kick in.

  • Is there a significance to the name foo here? If not, it should be more accurate and start with a capital letter as it's a user-defined type. The capitalization also applies to pipeline.

  • iter end = m_list.end(); seems pointless here. You can just use m_list.end() inside the loop statement.

    As m_list is not being modified inside the loop, you can instead use cbegin() and cend() for const-correctness.

    If you have C++11, you can use auto to replace the defined iterator inside the loop statement.

  • Your "pause" is okay, but you can also use std::cin.get() to do the same thing.

answered Feb 6, 2014 at 5:29
\$\endgroup\$
2
  • \$\begingroup\$ start with a capital letter as it's a user-defined type. The capitalization also applies to pipeline. If you could provide a reference here, it would be a kick in the nuts for my colleagues, claiming that "if STL does it, it's correct". \$\endgroup\$ Commented Apr 22, 2017 at 12:22
  • 1
    \$\begingroup\$ @Vorac: This answer might help, which also includes a quote from Stroustrup. \$\endgroup\$ Commented Apr 23, 2017 at 2:31
2
\$\begingroup\$

Using std::vector instead of std::list may be more efficient (both for speed and memory allocation). Advantages are explained in answer to this question.

Just change

typedef std::list<filter_function> filter_list;

to

typedef std::vector<filter_function> filter_list;
answered Apr 14, 2017 at 12:58
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.