Я надеюсь, что этот вопрос не слишком запутанный. Я понимаю, что метапрограммирование воздействует на типы, а не на объекты этих типов; тем не менее, я все еще пытаюсь добиться того же результата, 1) извлекая информацию о типе из класса, а затем 2) метафункции для этой информации о типе.
Объяснение моей ситуации с упрощенными выдержками кода выглядит следующим образом:
У меня есть класс-шаблон для матриц, который я называю Matrix_Base. В чем-то похожий на подход, использованный Эйгеном, я допускаю два варианта размера матрицы: либо фиксированный во время компиляции, либо фиксированный во время выполнения. Упрощенное объявление Matrix_Base:
template <typename Type, uint32_t rows_ = 1, uint32_t cols_ = 1,>
class Matrix_Base{
/*
...
*/
};
Матрица размера времени выполнения обозначается аргументом 0.
Проверка размера матрицы во время выполнения и во время компиляции довольно проста (используя boost::mpl):
typedef typename mpl::if_<
typename mpl::or_<
typename mpl::equal_to<
typename mpl::int_<rows_>::type,
mpl::int_<0>
>::type,
typename mpl::equal_to <
typename mpl::int_<cols_>::type,
mpl::int_<0>
>
>::type,
mpl::true_,
mpl::false_
>::type runtime_size_type;
Это было протестировано и работает нормально. Моя беда начинается примерно здесь...
В настоящее время я использую приведенный выше код boost::mpl следующим образом:
namespace internal {
template <uint32_t rows = 1, uint32_t cols_ = 1>
struct Runtime_Size_Helper {
typedef typename mpl::if_<
// REST OF THE BOOST::MPL code here //
>::type runtime_size_t
bool value() { return runtime_size_t::value;}
};
} // namespace
template <typename Type, uint32_t rows_ = 1, uint32_t cols_ = 1>
class Matrix_Base{
// ...
static constexpr uint32_t rows = rows_;
static constexpr uint32_t cols = cols_;
bool is_runtime_sized;
// ...
};
template <typename T, uint32_t R, uint32_t C>
bool Matrix_Base<T,R,C>::is_runtime_sized = internal::Runtime_Size_Helper<R,C>::value();
Это превращает результат этой функции mpl в член класса Matrix_Base. Все идет нормально.
Я хотел бы использовать некоторую форму косвенности, чтобы определить значение runtime_size_type, передав ему созданный объект. Согласно коду примера, единственной необходимой информацией для определения этого являются параметры uint32_t для столбца и строки.
Для созданного объекта Matrix_Base соответствующая информация никогда не изменится по сравнению со значениями типа компиляции. Размер матрицы будет неизменным; размер будет либо установлен из аргументов шаблона, либо -- для матриц размера времени выполнения -- через конструктор. В обоих случаях аргументы шаблона фиксированы и являются частью информации о типе. Я сохраняю эту информацию как статические переменные в классе, и я даже пытался добавить typedef со всеми параметрами шаблона как my_type typename typename Matrix_Base<T,rows_, cols_, ...> my_type
, но я не могу понять, как написать метафункцию, которой я могу передать объект Matrix_Base (очевидно, как ссылка или указатель) и повторно извлечь соответствующую информацию.
Я полностью открыт для включения (других) библиотек повышения, если они обеспечат необходимую функциональность.
Надеюсь, что это понятно. Пожалуйста, дайте мне знать, если здесь есть что-то неясное или просто глупое.
С уважением, Шмуэль
отредактировал текст, чтобы внести немного больше ясности в вопрос