Я ищу стандартный шаблон типа C++ 14, который статически (во время компиляции) вводит ссылку на функцию в качестве аргумента шаблона и реализует operator()
в качестве переадресации вызываемой функции.Существует ли стандартный шаблон шаблона шаблона статической функции?
Я знаю, что std::function
существует, но он хранит указатель на функцию как элемент данных. Я хочу, чтобы ссылка на функцию была встроена в подпись типа, чтобы тип обертки был пустым и по умолчанию-конструктив.
У меня есть рабочая реализация (с примером случая использования):
#include <cstring>
#include <iostream>
#include <memory>
// Implementation:
template <typename Ret, typename... Args>
struct fn_t {
template <Ret (Func)(Args...)>
struct fn_ref {
Ret operator() (Args &&...args) const {
return Func(std::forward<Args>(args)...);
}
};
};
// Example use case:
template <typename T>
using unique_c_ptr = std::unique_ptr<T, fn_t<void, void *>::fn_ref<std::free>>;
int main() {
// { char *, void (*)(void *) } (16 bytes)
std::unique_ptr<char[], decltype(&std::free)> ptr1(::strdup("Hello"), &std::free);
// { char *, fn_t<void, void *>::fn_ref<std::free> } (8 bytes)
unique_c_ptr<char[]> ptr2(::strdup("Hello"));
std::cout << sizeof ptr1 << '\n' // 16
<< sizeof ptr2 << std::endl; // 8
return 0;
}
ptr1
и ptr2
работу так, но ptr2
составляет половину размера, потому что не нужно хранить указатель на std::free
.
Мой вопрос: есть ли способ для стандартной библиотеки сделать это, так что мне не нужно определять fn_t
и fn_ref
?
Функция типа. –
@JoelCornett: Функция не является типом. Если вы попытаетесь предоставить 'std :: free' как аргумент типа, компилятор испустит ошибку:« несоответствие типа/значения в аргументе 1 в списке параметров шаблона »(« примечание: ожидается тип, полученный «свободный»). Функция * имеет * тип, но функция * не является типом. И тип функции не уникален для этой функции. 'decltype (std :: free)' is 'void (void *) throw()', и этот тип не имеет 'operator()'. –
ха-ха, это была «тип-о» с моей стороны. Я имел в виду обратное. –