Я реализую некоторые структуры данных, каждая из которых поддерживает набор команд, таких как INSERT value
.
Я использовал токенизатор для генерации вектора, содержащего каждое слово / значение.
Я хочу иметь возможность выводить в файл .txt время каждый вызов функции, плюс то, что функция вернула , если it возвращает что-то вернуть .
Например, если команда INSERT AVLTREE 4
, я хочу просто вывести время вызова avl.insert(4)
.
Если команда SEARCH AVLTREE 4
, я хочу вывести время вызова avl.search(4)
и его результат (например, "SUCCESS"
или "FAILURE"
).
Вероятно, в следующем коде много неправильного, но вот что я придумал:
Я создал два файла (.cpp / .hpp), которые содержат следующую самодействующую функцию-обертку, а также вариант и структуру:
// WRAPPER CPP
// file: wrap.cpp
#include "wrap.hpp"
#include <chrono>
#include <string>
#include <utility>
#include <boost/variant.hpp>
using std::chrono::high_resolution_clock;
using std::chrono::time_point;
using std::chrono::nanoseconds;
using std::string;
using std::to_string;
using std::forward;
using boost::get;
using boost::static_visitor;
using boost::apply_visitor;
// I'm overloading std::to_string, so it works on std::strings as well.
string to_string(const string &value)
{
return value;
}
// I want to apply to_string on whatever is inside my variant.
class to_string_visitor : public static_visitor<>
{
public:
template <typename T>
void operator()(T & operand) const
{
to_string(operand);
}
};
// Takes two points in time and returns the time
// between them in nanoseconds.
const nanoseconds::rep duration(const nanoseconds tpoints_difference) noexcept
{
const auto result = tpoints_difference.count();
return result;
}
// Generates a point in time.
const high_resolution_clock::time_point timeNow(void) noexcept
{
const auto result = high_resolution_clock::now();
return result;
}
// Here's where's the problematic magic happens:
// The ret boolean is set to true if the function F returns a value,
// otherwise, it is set to false.
//
// Variadic arguments are being taken and then std::forwarded to F.
template<typename F, typename... Args>
const output wrapper(bool ret, F function, Args&&... args) noexcept
{
// Generate a point in time, t1.
const high_resolution_clock::time_point t1 = timeNow();
// If F returns a result,
if (ret == true)
{
// assign it to result (my variant).
result = function(forward<Args>(args)...);
}
else
{
// just call F with Args forwarded.
function(forward<Args>(args)...);
}
// Generate another point in time, t2 and
// count the difference between t2 - t1.
const auto elapsed = duration(timeNow() - t1);
// Make whatever is inside result a string
// using std::to_string.
apply_visitor(to_string_visitor(), result);
// My struct
output out;
// which contains the time elapsed and
// the result returned
out.time = elapsed;
out.result = get<string>(result);
// I can theoretically use both time elapsed and
// result returned however I want. Hooray!..almost:(
return out;
}
Вот вариант result
:
// These are all the types a data structure function may return.
variant<int, unsigned, uint32_t, size_t, graph_size, string> result = 0;
graph_size
, просто для справки:
struct graph_size
{
unsigned vertices; //Number of vertices that the Graph currently contains
unsigned edges; //Number of edges that the Graph currently contains
};
И, наконец, структура output
:
typedef struct output
{
double time; // function call time
string result; // what function returned
// notice that if function returned nothing,
// result will be an empty string.
output() : time(0), result("") {}
} output;
Я пытаюсь использовать wrapper
примерно так:
AVL avl;
// stuff
auto out = wrapper(true, avl.insert, 4);
Я получаю следующую ошибку:
invalid use of non-static member function 'void AVL::insert(int)'
А вот еще один бонус, который намекает мне на то, что я испортил, но просто не могу понять:
no matching function for call to 'wrapper(bool, <unresolved overloaded function type>, unsigned int&)'
Есть мысли?
Я ценю все время, проведенное заранее:)
РЕДАКТИРОВАТЬ 1: название вопроса может быть не очень подходящим, я буду рад изменить, если у вас есть что-то хорошее