4

Вдохновленный элегантным способом автогенерации (случайных) экземпляров данного типа, например, в QuickCheck, я пытаюсь выяснить, как написать as-easy- to-use-as-possible платформа сравнения в C++. Я полагаю, что буду использовать шаблоны функций, возможно, с помощью новых функций на C++ 11, таких как вариативные шаблоны. Я надеюсь, что мне нужно только указать функцию или еще лучше шаблон функции и тип контейнера шаблона STL (в свою очередь его value_type), совместимый с аргументом (-ами) функции.Функция проверки QuickCheck-Like Template в C++

Я полагал, что тестирование функции с набором входов различного размера несколько похоже на то, как потоки устанавливаются и порождаются в C++ 11. Моя первая попытка будет скопировать конструктор thread класса и превратить его в benchmark функции, как

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

Я не уверен, следует ли использовать г-значение рефов здесь или нет. Однако f и args должны быть явно инстанцированы до вызова benchmark, что приводит к громоздкому неработоспособным.

Это привело ко мне, чтобы попытаться пропустить аргументы вызова и использовать только аргументы шаблона вместо:

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()); 
    } 
} 

называется

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

Однако, компиляция в настоящее время ошибки в

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() 

Я не уверен, может ли C++ обрабатывать перевод шаблона функции исключительно по аргументам шаблона nother вызывающая функция.

Это правильный способ сделать это или это невозможно в C++ 11? Я использую GCC-4.6.

+1

QuickCheck - это библиотека тестирования модулей, а не библиотека сравнения ... – kennytm

+1

Если вас интересуют другие решения, ознакомьтесь с моим [QuickCheck clone для C++ 11] (https://github.com/thejohnfreeman/autocheck). –

ответ

4

Если вам нужно поддерживать «более высокие» параметры, вы должны использовать template-template parameters. Кроме того, внутри шаблона f::g будет считаться значением, если оно не определено typename. Поэтому вы должны написать:

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

(Все они имеются в наличии перед C++ 11.)


Edit: Но вызов

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

не будет работать , потому что std::sort является перегруженной функцией шаблона, а не шаблоном класса. Вы не можете ссылаться только на std::sort, потому что это будет неоднозначно.

Если вы хотите работать с функциями, как std::sort, который не имеет никаких связанных контексты, вы можете передать указатель на функцию неоднозначности с перегрузкой использовать:

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>(); 

или

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); 

или просто вручную выберите, какую перегрузку вы хотели бы использовать, позволяя передавать общие функции:

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>); 
+0

Спасибо. Я все еще получаю сообщение об ошибке: 'tests/t_histogram.cpp: 56: 44: ошибка: нет соответствующей функции для вызова в 'benchmark_container()'тестов/t_histogram.cpp: 56: 44: примечание: кандидат: test /../ benchmark.hpp: 32: 6: note: template