【问题标题】:C++ member function template using templateC++成员函数模板使用模板
【发布时间】:2016-05-17 14:54:21
【问题描述】:

抱歉,标题混淆了。我不知道还能怎么说。示例应自行解释。

我发现了一个名为 typemaps 的东西,并将其用于我的代码,如下所示:

template<typename T>
struct typemap
{
    static const int INDEX;
};

template<>
const int typemap<Type1>::INDEX = 1;
template<>
const int typemap<Type2>::INDEX = 3;
template<>
const int typemap<Type3>::INDEX = 11;

Type1 Type2 & Type3 是结构体,使用起来就像这里的类型。 INDEX 编号不能在结构内部,因为可能存在另一个具有不同编号但具有相同类型对象的类型映射。所以类型图适用于集合中不同顺序的结构,如矢量,因为顺序对我很重要。

接下来是非模板类,它具有 Type1-3 作为属性。而我要做的是将这些属性插入向量中,这是在 std::function 的帮助下完成的。但我需要采用通用类型映射并将其用作插入向量的索引。

我认为它唯一可行的方法是使用更多模板。类似于下一个代码的东西,但这不是正确的方法,因为我还是模板的新手,我需要帮助才能正确编写它,所以函数体 toVector 根据需要开始工作。

class MyClass
{
  Type1 type1_;
  Type2 type2_;
  Type3 type3_;
  ..

  template<typename T>
  void toVector(T& typemap)
  {
    std::vector<..> vect;
    vect.resize(..);
    vect[typemap<Type1>::INDEX] = type1_.someFunction(..);
    vect[typemap<Type2>::INDEX] = type2_.someFunction(..);
  }

};

我确定我在成员函数中使用了错误的模板,我不知何故需要说 T 参数也有一些模板参数。对不起我的英语,不是母语人士。也很抱歉“..”这与我的问题无关,它会弄乱代码。

【问题讨论】:

  • 您正在寻找template template parameters
  • 当人们改掉将常量命名为大写的坏习惯时?
  • @Slava 为什么这是一个坏习惯?
  • @ChrisG 常量在 C++ 中被用作预处理宏,预处理宏为大写以避免命名冲突。这种习惯就是从那里养成的。常量不再是宏,出于完全相同的原因,最好不要使用大写。

标签: c++ templates c++11


【解决方案1】:

Barry 的回答是一种更好的方式来做你想做的事情,但这里是你关于有一个模板参数的具体问题的答案,它本身就是一个带有一个参数的模板:

  template<template<typename> class type_with_one_template_parameter>
  void toVector()
  {
    std::vector<..> vect;
    vect.resize(..);
    vect[type_with_one_template_parameter<Type1>::INDEX] = type1_.someFunction(..);
    vect[type_with_one_template_parameter<Type2>::INDEX] = type2_.someFunction(..);
  }

不清楚为什么该函数在您的原始示例中具有 T&amp; typemap 参数,因此我将其删除。

【讨论】:

    【解决方案2】:

    我们不为INDEX 添加显式特化,而是创建一个可以传递的实际对象类型typemap。首先是一些样板:

    template <class T>
    struct tag_type {
        using type = T;
    };
    
    template <class T>
    constexpr tag_type<T> tag{};
    
    template <int I>
    using int_ = std::integral_constant<int, I>;
    

    现在,我们为index() 创建一个带有一堆重载的对象,它们采用不同的tag_types 并返回不同的int_s。:

    struct typemap {
        constexpr int_<3> size() const { return {}; }
    
        constexpr int_<1> index(tag_type<Type1> ) const { return {}; }
        constexpr int_<3> index(tag_type<Type2> ) const { return {}; }
        constexpr int_<11> index(tag_type<Type3> ) const { return {}; }
    };
    

    这是您可以传递给函数模板并直接使用的东西:

      template<typename T>
      ??? toVector(T const& typemap)
      {
          std::vector<..> vect;
          vect.resize(typemap.size());
    
          vect[typemap.index(tag<Type1>)] = ...;
          vect[typemap.index(tag<Type2>)] = ...;
          vect[typemap.index(tag<Type3>)] = ...;
      }
    

    【讨论】:

    • 我对 constexpr 不是很熟悉,但不应该是 &lt;class T&gt; constexpr tag_type&lt;T&gt; tag(){}; 吗?顺便提一句。 thx 对于这种解决方案,我会尝试一下,它看起来确实很有趣,但是我看到我仍然需要学习很多东西,这里使用的一些代码结构对我来说是新的。
    • @Lukin 不 - 额外的括号有什么用?
    • 没有它就无法编译,我在g++ -std=c++11 不确定这是不是问题,我得到了error: template declaration of ‘constexpr const tag_type&lt;T&gt; tag’
    • @Lukin 变量模板是 C++14 特性。使用 C++11,您必须替换我使用 tag&lt;T&gt; 的位置来显式编写 tag_type&lt;T&gt;{}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多