【问题标题】:Generating C++ typename by concatenating template parameter with a string通过将模板参数与字符串连接来生成 C++ 类型名
【发布时间】:2015-02-02 22:49:03
【问题描述】:

我正在尝试找出一种使用 Boost::MPL 生成类型名的方法,该类型名是模板参数和字符串的连接。

我有一对名为:XXProvider 的类。后者是一个工厂类,它实例化从前一种类型继承的对象。

模板类旨在在运行时管理类型的实例化:它包含除其他外的 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&lt;T&gt; 是一个返回类型名 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_strmpl::string 或它们的正确用法,并且我无法按照收到的错误消息进行操作。上面写的代码给了我错误信息:

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

(这里的 foo 是模板参数——Plugin_Manager&lt;foo&gt;

我意识到如果我使用大型宏而不是 c++ 模板,我可能会完成这项工作,但如果完全可能,我真的希望避免这种情况。

非常感谢任何建议。

谢谢- 什穆尔

【问题讨论】:

  • 宏是通过组合现有标识符来创建新标识符的唯一方法,抱歉。模板做不到。
  • 你所说的对我来说没有多大意义。如果您打算使用表达式Get_provider_Type&lt;Base_Type&gt;::type 来指定向量的模板参数,您只需要提供一个类型。您根本不需要为其生成名称。
  • 也许 generate 是错误的术语。 Plugin_Manager&lt;foo&gt; 需要包含一个 std::vector&lt;fooProvider&gt; - 我想要一个元函数 Get_Provider_Type&lt;foo&gt;::type 它将为我返回类型 fooProvider,但我不知道如何编写这个元函数(或者即使它是可能的-- 根据上面@MarkRansom 的评论)。
  • @ShmuelLevine 这是不可能的。最好在foo 中简单地提供一个public: typedef fooProvider provider;。这样,每个类都可以定义自己的提供者类型,而不必遵循任何特定的命名约定。然后您只需将 typename T::provider 作为提供程序类型。
  • @cdhowie,总而言之,这是一种明智的做法,而且由于它只需要在基类中,因此影响很小。我不知道为什么我事先没有想到这一点……我想我最近一直在想 TMP,并且希望比昨天学到更多……

标签: c++ templates template-meta-programming boost-mpl


【解决方案1】:

嗯,你不能通过连接字符串和模板参数来获得类型名,但如果你的意图是......

我想要一个元函数 Get_Provider_Type::type 它将为我返回类型 fooProvider

你可以简单的在foo中定义类型:

struct foo {
    using provider = fooProvider;
};

如果您需要它,您可以实现您的“元函数”,它将适用于所有定义 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;
};

【讨论】:

  • 谢谢。我不知道为什么我以前没有想到这种方法。它很优雅,并且对于我的特定应用程序(如我原来的帖子上面的 cmets 中提到的)来说,效果出奇的好。我想我已经下定决心要找到一个 mpl 和 concatenation 的解决方案,所以这甚至没有发生在我身上。谢谢!
  • 我认为 C++ 的模板系统是图灵完备的?这是否意味着有某种方法可以做到这一点?
猜你喜欢
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 2018-09-23
  • 2013-11-26
相关资源
最近更新 更多