Всем доброго времени суток.
Есть примерно такой код (навеяно библиотекой
sqlite_orm) на С++17:
#include <tuple>
#include <type_traits>
//------
auto make_object()
{
return std::make_tuple(1, 2.0, "3"); // Тут возвращается достаточно сложный тип, основанный на вариадиках, не суть
}
//------
template<auto (*T)()> // ??? template<typename T = ...>
struct storage
{
using storage_t = std::invoke_result_t<decltype(T)>;
storage_t _data;
storage();
};
template<auto (*T)()>
storage<T>::storage()
: _data{(*T)()}
{
}
//------
struct object_storage
: storage<make_object>
{};
int main()
{
object_storage st;
return 0;
}
Вопрос: как ещё можно положить результат вызова make_object() в поле класса?
Меня несколько напрягает такой вывод типа. CLion начинает плющить, он не справляется с парсингом и кодогенерацией. Да и хочется синтаксически более читаемой конструкции.
Здравствуйте, SaZ, Вы писали:
SaZ>Вопрос: как ещё можно положить результат вызова make_object() в поле класса?
"Лобовой" вариант, который первым приходит в голову — использование частичной специализации:
http://coliru.stacked-crooked.com/a/ecccd0e27f6939e9
#include <tuple>
//------
auto make_object()
{
return std::make_tuple(1, 2.0, "3"); // Тут возвращается достаточно сложный тип, основанный на вариадиках, не суть
}
//------
template<auto>
struct storage;
template<typename R, R(*F)()>
struct storage<F>
{
R _data{F()}; // Здесь default member initializer вместо определения default constructor
};
//------
// Здесь простой using-declaration вместо определения нового класса с наследованием
using object_storage = storage<make_object>;
int main()
{
object_storage st;
}
Здравствуйте, rg45, Вы писали:
R>"Лобовой" вариант, который первым приходит в голову — использование частичной специализации:
R>http://coliru.stacked-crooked.com/a/ecccd0e27f6939e9
R>...
Спасибо, внезапно придумал написать
template<auto T>. В моём случае тип вывелся корректно.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, SaZ, Вы писали:
SaZ>>Спасибо, внезапно придумал написать template<auto T>. В моём случае тип вывелся корректно.
R>Здесь еще SFINAE напрашивается прикрутить — чтоб при попытке параметризовать шаблон чем-нибудь левым, ошибка возникала в месте использования, а не в потрохах шаблонного класса.
Да. Но подожду концептов
Пишу консольную утилиту для кодогенерации в рамкаж текущих нужд проекта. Пока не особо заморачиваюсь над сопровождаемостью кода.