Shmuel Levine
Shmuel Levine

Reputation: 560

Generating C++ typename by concatenating template parameter with a string

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

Answers (1)

eerorika
eerorika

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

Related Questions