1

I have a list of functions that return bools. I want to iterate through the list of functions and write a message for each one "Test 1 passed", "Test 2 failed" etc.

My current solution is to create a vector of function pointers, push back each function and then loop through the vector. Code below. Is there a way to avoid the container without repeating the generic message (pass/fail) code for each test (imagine there would be hundreds of tests). It feels as if the vector is unnecessary or that there must be a more elegant solution for this.

typedef bool (*Tests)(); std::vector<Tests> tests; tests.push_back(FASTA_FILE_READER_TEST); tests.push_back(EXACT_MATCH_TEST); for (int i = 0; i < tests.size(); i++) { std::cout << "Test " << i + 1 << (tests[i]() ? " PASSED" : " FAILED") << std::endl; } 
5
  • 3
    What's not elegant about using a container to store things? Commented Jul 24, 2012 at 12:27
  • I can guarantee you that out of all the answers that get posted here, this will be the least convoluted. Commented Jul 24, 2012 at 12:31
  • I think it just feels like 'overkill' for this task. For example, aren't vectors given extra capacity as they are pushed into? Which seems pointless because I already know in advance how tests there are, I only have them in a container here because I want to loop through them. Commented Jul 24, 2012 at 12:33
  • Out of topic, but I suggest you to have a look at some testing frameworks like CppUnit (sourceforge.net/apps/mediawiki/cppunit/…) Commented Jul 24, 2012 at 12:38
  • 1
    You've got a very nice solution. Use reserve if the "wasted" capacity bothers you (it's very rarely a problem). Commented Jul 24, 2012 at 12:39

4 Answers 4

3

Is there anything stopping you using an array?

#include <iostream> bool FASTA_FILE_READER_TEST() { return false; } bool EXACT_MATCH_TEST() { return false; } int main() { typedef bool (*Tests)(); Tests tests[] = {FASTA_FILE_READER_TEST, EXACT_MATCH_TEST}; for (int i = 0; i < sizeof(tests)/sizeof(Tests); i++) { std::cout << "Test " << i + 1 << (tests[i]() ? " PASSED" : " FAILED") << std::endl; } } 
Sign up to request clarification or add additional context in comments.

3 Comments

No, nothing stopping me. I like this way.
However, it doesn't work! ideone.com/a8xDG. Both tests pass when one should fail?
Between us it seems we forgot to actually call the function in the loop. I've modified ((*tests[i]) to tests[i]() and it works as expected!
2

You could use a function to do that:

template<typename Functor> void test(Functor& functor){ static int i = 0; bool ret = functor(); if(ret){ std::cout << "Test " << i++ << " passed" << std::endl; } else { std::cout << "Test " << i++ << " failed" << std::endl; } } void main(){ test(FASTA_FILE_READER_TEST); test(EXACT_MATCH_TEST); } 

1 Comment

I would probably have the counter as a static variable inside the test function, and increase it there instead.
2

If you can use C++11 features:

#include <array> #include <iterator> #include <algorithm> #include <iostream> typedef bool (*Test)(); std::array<Test, 2> tests {{ FASTA_FILE_READER_TEST, EXACT_MATCH_TEST }}; void TestAll() { size_t i = 1; std::for_each(std::begin(tests), std::end(tests), [&i](Test& t) { std::cout << "Test " << i++ << (t() ? " PASSED" : " FAILED") << std::endl; }); } 

Demo.

It's another way of doing what you've already got (and your way is just fine, IMO). If the extra capacity a vector might have set aside bothers you, you can call shrink_to_fit() on it when you're done pushing back.

1 Comment

looks good. seems like you're right though..the vector approach is not so bad after all! my sense of what 'good' C++ code looks like is still forming so every time I get a hunch that something could be improved I use SO to verify. It has been a very useful learning approach so far.
0

Create a class for each test. Then one static instance of each class. Contructors of classes runs tests.

This of course may cause problems, because tests are executed before main() function is called.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.