в настоящее время я работаю над динамической контейнерной структурой, которая представляет одно значение модуля или имеет вектор указателей с тем же типом контейнера. Контейнер имеет интерфейс optional<T> expect_value<T>()
。 Для типов подов реализация проста. Для значения, отличного от pod, я бы назвал expect_value<tuple<args...>>()
, args
также будет кортежем. Но при реализации этой функции сталкиваюсь с проблемой: как перенаправить a.expect_value<tuple<args...>>()
на a.expect_value_tuple<args...>>()
. Например, вызов a.expect_value<tuple<int,int>()
вернет результат a.expect_value_tuple<int, int>()
. Поскольку аргумент пуст, я не могу использовать вывод распакованных аргументов. Тогда весь проект просто не может больше развиваться. Любые идеи? Ниже приведен минимальный пример моего намерения.
#include <tuple>
#include <vector>
#include <optional>
#include <functional>
using namespace std;
template<typename T>
struct is_tuple_impl : std::false_type {};
template<typename... Ts>
struct is_tuple_impl<std::tuple<Ts...>> : std::true_type {};
template<typename T>
struct is_tuple : is_tuple_impl<std::decay_t<T>> {};
class my_container;
template<typename... args, size_t... arg_idx>
optional<tuple<args>...> get_tuple_value_from_vector(const vector<my_container*>& v_list, std::index_sequence<arg_idx...>)
{
auto temp_result = make_tuple((*v_list[arg_idx]).expect_value<arg>()...);
if(!(get<arg_idx>(temp_result) &&...))
{
return nullopt;
}
return make_tuple(get<arg_idx>(temp_result).value()...);
}
class my_container
{
public:
int value_type; // 1 for v_int 2 for v_list 0 empty
union
{
int v_int;
};
vector<my_container*> v_list;
template<typename T>
optional<T> expect_simple_value();
template<typename... args>
optional<tuple<args...>> expect_tuple_value();
template<typename T>
optional<T> expect_value();
};
template <typename T>
optional<T> my_container::expect_simple_value()
{
return nullopt;
}
template <>
optional<int> my_container::expect_simple_value()
{
if(value_type == 1)
{
return v_int;
}
return nullopt;
}
template<typename... args>
optional<tuple<args...>> my_container::expect_tuple_value()
{
if(v_list.size() == 0)
{
return nullopt;
}
for(const auto i: v_list)
{
if(!i)
{
return nullopt;
}
}
auto the_tuple_size = sizeof...(args);
if(v_list.size() != the_tuple_size)
{
return nullopt;
}
return get_tuple_value_from_vector<args...>(v_list, index_sequence_for<args...>{});
}
template <typename T>
optional<T> my_container::expect_value()
{
if(is_tuple<T>::value)
{
return expect_tuple_value<T>();
}
else
{
return expect_simple_value<T>();
}
}
int main()
{
my_container test_value;
test_value.value_type = 1;
test_value.v_int = 1;
auto result = test_value.expect_value<tuple<int, int>>();
if(result)
{
return 0;
}
else
{
return 1;
}
}
Суть проблемы - это строка return expect_tuple_value<T>();
Когда логика идет туда, T должно быть tuple<args...>
, но я хочу вернуть return expect_tuple_value<args...>()
.
enum class
вместоint
дляint value_type
. - person Max Langhof   schedule 12.12.2018