QuickCheck-Like Template Benchmarking Check Function in C ++

Inspired by Haskell in an elegant way to auto-generate (random) instances of a given type, for example, in QuickCheck, I'm trying to figure out how to write both an easy-to-use and a possible comparison method in C ++. I believe that I will use function templates, perhaps with the help of new functions in C ++ 11, such as variable templates. I hope that I only need to specify the function or, even better, the function template and the container type of the STL template (in turn, its value_type ), compatible with the argument (s) of the function.

I realized that benchmarking a function with a set of inputs of various sizes is somewhat similar to how threads are set up and spawned in C ++ 11. My first attempt was to copy the constructor of the thread class and turn it into a benchmark function as

 template< class Function, class ...Args > inline void benchmark( Function&& f, Args&&... args ); 

I'm not sure if r-value refs should be used here. However, f and args must be explicitly created before the benchmark called, which leads to cumbersome non-functional use.

This results in me trying to skip the call arguments and use only the arguments instead:

 namespace pnw { template <template <typename> class Function, typename Container> inline void benchmark_container() { Function<typename Container::iterator> f; Container c(10); f(c.begin(), c.end()); } } 

called

 typedef int T; typedef std::vector<T> C; pnw::benchmark_container<std::sort, C>(); 

However, now error compilation is performed as

 tests/t_histogram.cpp: In function 'void test_benchmark()': tests/t_histogram.cpp:56:44: error: no matching function for call to 'benchmark_container()' tests/t_histogram.cpp:56:44: note: candidate is: tests/../benchmark.hpp:32:6: note: template<template<class> class Function, class Container> void pnw::benchmark_container() 

I'm not sure if C ++ can handle the translation of a function template solely on the template arguments of another calling function.

Is this the right way to do this or is it impossible in C ++ 11? I am using GCC-4.6.

+4
source share
1 answer

If you need to support "higher" parameters, you should use template template parameters . Also, inside the template f::g will be considered a value if it is not defined by typename . Therefore, you should write:

 template <template <typename> class Function, typename Container> // <-- inline void benchmark_container() { Function<typename Container::iterator> f; // <-- ... 

(All of them are available before C ++ 11.)


Edit: But the challenge

 benchmark_container<std::sort, C>(); 

will not work because std::sort is an overloaded template function, not a class template. You cannot only refer to std::sort , because it will be ambiguous.

If you want to work only with functions such as std::sort that have no associated contexts, you can pass a function pointer to disambiguate using overload:

 template <typename Container, void (*func)(typename Container::iterator, typename Container::iterator)> inline void benchmark_container() { Container c (10); func(c.begin(), c.end()); } benchmark_container<std::vector<int>, std::sort>(); 

or

 template <typename Container> inline void benchmark_container(void (*func)(typename Container::iterator, typename Container::iterator)) { Container c (10); func(c.begin(), c.end()); } benchmark_container<std::vector<int>>(std::sort); 

or simply manually select which overload you want to use, allowing you to transfer common functions:

 template <typename Container, typename F> inline void benchmark_container(const F& function) { Container c (10); function(c.begin(), c.end()); } benchmark_container<std::vector<int>>(std::sort<std::vector<int>::iterator>); 
+4
source

Source: https://habr.com/ru/post/1391449/


All Articles