Reputation: 560
I'm trying to figure out a way to use Boost::MPL to generate a typename which is the concatenation of a template parameter and a string.
I have pairs of classes which are named: X
and XProvider
. The latter is a factory class which instantiates objects inherited from the former type.
The template class is intended to manage the instantiation of types at runtime: it contains, among other things, an unordered_map and some other misc. members.
What I am ultimately trying to achieve is a metafunction that looks something like this:
Given the class
template <typename T>
class Plugin_Manager{
using Base_Type = T;
std::vector<Get_Provider_Type<Base_Type>::type *> m_provider_collection;
*/ ... /*
};
Where Get_Provider_Type<T>
is a metafunction which returns a typename TProvider.
Based on this answer, I think that the metafunction should look something along the lines of this:
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;
};
However, I am really not understanding mpl::c_str
or mpl::string
or their correct usage, and I cannot follow the error messages that I am receiving. The code as written above gives me the error message:
error C2039: 'value_type' : is not a member of 'foo'
(foo here being the template argument -- Plugin_Manager<foo>
)
I realize that I can likely make this work if I use a large macro rather than c++ template, but I would really like to avoid that if at all possible.
I'd really appreciate any suggestions.
Thanks- Shmuel
Upvotes: 1
Views: 3833
Reputation: 238321
Well, you can't get a typename from concatenating strings with template parameters, but if your intention is...
I'd like to have a metafunction Get_Provider_Type::type which will return for me the type fooProvider
You can simply define the type in foo
:
struct foo {
using provider = fooProvider;
};
If you need it, you can implement your "metafunction" that will work with all types that define T::provider
template<class T>
struct Get_Provider_Type {
using type = typename T::provider;
};
Which can be useful if you can't modify foo
to define the type. Then you can specialize Get_Provider_Type
instead:
template<>
struct Get_Provider_Type<foo> {
using type = fooProvider;
};
Upvotes: 2