【发布时间】:2015-02-02 22:49:03
【问题描述】:
我正在尝试找出一种使用 Boost::MPL 生成类型名的方法,该类型名是模板参数和字符串的连接。
我有一对名为:X 和 XProvider 的类。后者是一个工厂类,它实例化从前一种类型继承的对象。
模板类旨在在运行时管理类型的实例化:它包含除其他外的 unordered_map 和其他一些杂项。成员。
我最终想要实现的是一个看起来像这样的元函数:
给定班级
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> 是一个返回类型名 TProvider 的元函数。
基于this answer,我认为元函数应该是这样的:
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++ 模板,我可能会完成这项工作,但如果完全可能,我真的希望避免这种情况。
非常感谢任何建议。
谢谢- 什穆尔
【问题讨论】:
-
宏是通过组合现有标识符来创建新标识符的唯一方法,抱歉。模板做不到。
-
你所说的对我来说没有多大意义。如果您打算使用表达式
Get_provider_Type<Base_Type>::type来指定向量的模板参数,您只需要提供一个类型。您根本不需要为其生成名称。 -
也许 generate 是错误的术语。
Plugin_Manager<foo>需要包含一个std::vector<fooProvider>- 我想要一个元函数Get_Provider_Type<foo>::type它将为我返回类型fooProvider,但我不知道如何编写这个元函数(或者即使它是可能的-- 根据上面@MarkRansom 的评论)。 -
@ShmuelLevine 这是不可能的。最好在
foo中简单地提供一个public: typedef fooProvider provider;。这样,每个类都可以定义自己的提供者类型,而不必遵循任何特定的命名约定。然后您只需将typename T::provider作为提供程序类型。 -
@cdhowie,总而言之,这是一种明智的做法,而且由于它只需要在基类中,因此影响很小。我不知道为什么我事先没有想到这一点……我想我最近一直在想 TMP,并且希望比昨天学到更多……
标签: c++ templates template-meta-programming boost-mpl