2014-12-04 4 views
1

Я пытаюсь выяснить способ использования Boost :: MPL для генерации имени типа, который является конкатенацией параметра шаблона и строки.Создание C++ typename путем конкатенации параметра шаблона со строкой

У меня есть пары классов, которые называются: X и XProvider. Последний - фабричный класс, который создает объекты, унаследованные от прежнего типа.

Класс шаблона предназначен для управления созданием типов во время выполнения: он содержит, помимо прочего, unordered_map и некоторые другие разное. члены.

То, что я в конечном счете пытается достичь, это metafunction, который выглядит примерно так:

Учитывая класс

template <typename T> 
class Plugin_Manager{ 

    using Base_Type = T; 

    std::vector<Get_Provider_Type<Base_Type>::type *> m_provider_collection; 

     */ ... /* 

}; 

Где Get_Provider_Type<T> является metafunction, который возвращает TYPENAME TProvider.

на основе this answer, я думаю, что metafunction должен выглядеть по линии этого:

template < typename Str1, typename Str2 > 
    struct concat : boost::mpl::insert_range < Str1, typename boost::mpl::end<Str1>::type, Str2 > {}; 


    template <class T> struct Get_Provider_Type{ 
     typedef typename boost::mpl::string<boost::mpl::c_str<T>::value>::type Base_Name; 
     typedef boost::mpl::string<'Prov', 'ider'> Suffix; 

     typedef typename concat<Base_Name, Suffix>::type type; 
    }; 

Однако, я действительно не понимая mpl::c_str или mpl::string или их правильное использование, и я не могу следовать за ошибки сообщения, которые я получаю. Код, как написано выше, дает мне сообщение об ошибке:

error C2039: 'value_type' : is not a member of 'foo' 

(Foo здесь будучи шаблон аргумент - Plugin_Manager<foo>)

Я понимаю, что, вероятно, может сделать эту работу, если я использую большой макрос, а не C++, но я бы действительно хотел бы избежать этого, если вообще возможно.

Я бы очень признателен за любые предложения.

Шмуэль Благодарения и

+1

Макросы являются единственным способом создания новых идентификаторов путем объединения существующих, извините. Шаблоны не могут этого сделать. –

+0

То, что вы говорите, не имеет для меня большого смысла. Если вы намерены использовать выражение 'Get_provider_Type :: type', чтобы указать аргумент шаблона для вектора, вам нужно только указать тип. Вам вообще не нужно генерировать имя для него. – pmr

+0

Возможно, _generate_ - неправильный термин. 'Plugin_Manager ' должен содержать 'std :: vector ' - Я хотел бы иметь metafunction 'Get_Provider_Type :: type', который вернет мне тип' fooProvider', но я не знаю, как напишите это metafunction (или даже если это возможно - за комментарий @ MarkRansom выше). –

ответ

2

Ну, вы не можете получить TypeName конкатенации строк с параметрами шаблона, но если вы задумали ...

Я хотел бы иметь metafunction Get_Provider_Type :: тип, который будет возвращать для меня тип fooProvider

Вы можете просто определить тип в foo:

struct foo { 
    using provider = fooProvider; 
}; 

Если вам это нужно, вы можете реализовать свой «metafunction», который будет работать со всеми типами, которые определяют T::provider

template<class T> 
struct Get_Provider_Type { 
    using type = typename T::provider; 
}; 

, которые могут быть полезны, если вы не можете изменить foo для определения типа. Тогда вы можете специализироваться Get_Provider_Type вместо:

template<> 
struct Get_Provider_Type<foo> { 
    using type = fooProvider; 
}; 
+0

Спасибо. Я не знаю, почему я раньше не думал об этом. Он элегантен и будет работать на удивление хорошо для моего конкретного приложения (как упоминалось в комментариях выше на моем оригинальном посте). Наверное, я решил, что нашел решение с mpl и конкатенацией, поэтому это даже не произошло. Благодаря! –

+0

Я думал, что система шаблонов C++ была Turing-complete? Разве это не означает, что есть какой-то способ сделать это? –

Смежные вопросы