Второй аргумент, ожидаемый преобразованием, - это унарная операция, которую вы не проходите.
В вашем случае my_type
не является metafunction
, так как mpl ожидает, так как он использует список переменных параметров.
metafunction
в простейшем случае выставляет type
ЬурейеЕ или ststic bool
value
. Например:
template <typename T>
struct add_pointer {
using type = T*;
};
Обратите внимание, как add_pointer
преобразует предоставленный параметр шаблона. Это пример операции unary
, так как он принимает только один параметр шаблона T
.
В вашем примере my_type
чисто типа и не может быть использован в качестве metafunction или операций, поскольку она не удовлетворяет критерии metafunction
в соответствии с требованиями transform
metafunction, который имеет type
поля, чтобы указать преобразованный тип.
В некоторых случаях простой шаблонный тип преобразуется в metafunction
, как описано в разделе Detailed Reasoning
ниже.
Doc ссылка: http://www.boost.org/doc/libs/1_31_0/libs/mpl/doc/ref/Reference/transform.html
Код:
#include <boost/mpl/vector.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/equal.hpp>
#include <type_traits>
#include <typeindex>
#include <iostream>
template <class... T>
struct my_type{};
using namespace boost::mpl;
using test_type = vector<int, double>;
template <typename T>
struct add_my_type {
using type = my_type<T>;
};
using result_type = typename transform< test_type, add_my_type<_1> >::type;
int main() {
static_assert (equal<result_type, vector< my_type<int>, my_type<double> >>::value, "Nope!!");
std::cout << typeid(result_type).name() << std::endl;
}
LIVE DEMO
Подробный Причина
Причина пояснялось выше довольно краток должно быть достаточно, чтобы ответить на этот вопрос. Но давайте вдаваться в подробности настолько, насколько смогу.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не являюсь экспертом в области boost :: mpl.
В соответствии с комментарием ниже по ОП, исходный код работает, если мы изменим my_type
на:
template <class T>
struct my_type{};
Но это не идет хорошо, что я уже говорил ранее operation
т.е. нужен type
идентификатор.Итак, давайте посмотрим, что MPL делает под капотом:
struct transform
несколько выглядит как:
template<
typename Seq1 = mpl::na
, typename Seq2OrOperation = mpl::na
, typename OperationOrInserter = mpl::na
, typename Inserter = mpl::na
>
struct transform {
boost::mpl::eval_if<
boost::mpl::or_<
boost::mpl::is_na<OperationOrInserter>,
boost::mpl::is_lambda_expression<my_type<mpl_::arg<1> > >,
boost::mpl::not_<boost::mpl::is_sequence<my_type<mpl_::arg<1> > > >,
mpl_::bool_<false>,
mpl_::bool_<false>
>,
boost::mpl::transform1<
boost::mpl::vector<int, double>,
my_type<mpl_::arg<1>>,
mpl_::na
>,
boost::mpl::transform2<boost::mpl::vector<int, double>,
my_type<mpl_::arg<1> >,
mpl_::na, mpl_::na>
>
};
Важной частью посмотреть здесь является is_lambda_expression
metafunction, который в основном проверяет, если ваш Operation
удовлетворяет требование о metafunction
.
После применения некоторых тяжелых макро- и шаблонные машин и специализаций, выше проверка синтезирует ниже структур:
template<
typename IsLE, typename Tag
, template< typename P1 > class F
, typename L1
>
struct le_result1
{
typedef F<
typename L1::type
> result_;
typedef result_ type;
};
Здесь F
вашего my_type
и L1
является placeholder
. Таким образом, по существу вышеуказанная структура - это всего лишь add_my_type
, которые я показал в своем первоначальном ответе.
Если я доволен, le_result1
- это operation
, который будет выполнен на вашем sequence
.
Благодарю вас за помощь. У меня создалось впечатление, что 'my_type <_1>' по существу преобразуется позже в унарный класс метафонов через mpl :: lambda. Я все еще не совсем понимаю, почему это не так, поскольку один аргумент передается 'my_type'. Не могли бы вы объяснить немного больше, почему 'my_type <_1>' не считается допустимым унарным классом метафоров, пожалуйста? – linuxfever
Обновил мой ответ. Надеюсь, теперь это должно быть ясно. – Arunmu
Я боюсь, что не согласен с «как требуется метафоном преобразования, который имеет поле типа, указывающее преобразованный тип». Например, если вы меняете 'my_type' на' template struct my_type {} ', код компилируется и дает желаемый результат, даже если' my_type' до сих пор не раскрывает поле 'type'. –
linuxfever