Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;使用traits更改模板方法的行为_C++_Templates_Traits - Fatal编程技术网

C++ C++;使用traits更改模板方法的行为

C++ C++;使用traits更改模板方法的行为,c++,templates,traits,C++,Templates,Traits,我有一个模板,我有方法T get(int I)和set(int I,T val)。我必须让traits类改变的不是行为,而是set和get所拥有的论点 template<typename T,int Roz> class Wektor{ public: T tab[Roz]; T get(int i) { return tab[i]; } void set(T val,int i) { tab[i]=val; } } 双重的 double ge

我有一个
模板
,我有方法
T get(int I)
set(int I,T val)
。我必须让traits类改变的不是行为,而是
set
get
所拥有的论点

template<typename T,int Roz>
class Wektor{
public:
 T tab[Roz];
 T get(int i)
 {
     return tab[i];
 }
 void set(T val,int i)
 {
     tab[i]=val;
 }
 }
双重的

 double get(int i);
 void set(double val,int i);
对于其他类型:

T* get(int i);
void set(T* val,int i);
我们必须在性状上做到这一点,而不是通过模板的专门化

所以我这样写:

template<typename T,int Roz>
class traitsWektor
{
public:
T tab[Roz];
T get(int i)
{
    return tab[i];
}
void set(T val,int i)
{
    tab[i]=val;
}
}
模板
阶级叛军
{
公众:
T标签[Roz];
T获取(int i)
{
返回标签[i];
}
无效集(T val,int i)
{
tab[i]=val;
}
}
所以我在这里卡住了。我想我应该

template<typename T, int Roz>
class Wektor : public traitsWektor<T,Roz>
模板
Wektor类:公共列车Wektor

但我不确定这是不是正确的,现在仍然是这样

您应该将类模板(Wektor)和参数类型推断分开:

template <class T>
struct WektorParamTraits {
  typedef T const& type;

  //or if you might have different types as getter return type and setter arg
  typedef T const& getterReturn;
  typedef T const& setterArg;
};
模板
结构WektorParameters{
typedef T const&type;
//或者您可能有不同的类型,如getter返回类型和setter arg
typedef T const&getterReturn;
typedef T const&setterArg;
};
在这种情况下,T是getter/setter参数的“默认”类型。专门为你需要的任何类型。 现在,类定义应该如下所示:

template<typename T,int Roz>
class Wektor{
  T tab[Roz]; //make member variables private
public:
  typename WektorParamTraits<T>::getterReturn get(int i) //const?
  {
    return tab[i];
  }

  void set(typename WektorParamTraits<T>::setterArg val,int i)
  {
    tab[i]=val;
  }
};
模板
韦克托级{
T tab[Roz];//使成员变量私有
公众:
typename WektorParamTraits::getterReturn get(int i)//const?
{
返回标签[i];
}
void set(类型名称WektorParamTraits::setterArg val,int i)
{
tab[i]=val;
}
};
更新:如评论中所述,您可能需要为get和set定义其他实现,例如,如果您的返回类型是指针。有几种不同的方法可以做到这一点:

  • 在traits中定义函数,以便在
    选项卡[i]
    和参数/返回值之间正确转换
  • 如果只涉及指针和非指针,请提供两个版本的getter和setter,并使用
    std::enable_If
    std::is_pointer
    以及禁用其中一个所需的任何其他工具
  • 使用您在这里发布的简单类定义,并将其专门化为不使用常规引用的少数类型。任何进一步的功能都应该进入一个非专门化的子类

  • 方法2将非常冗长且难以阅读。方法1也会很冗长,因为除了数组定义之外,几乎所有的东西都会委托给traits类,所以也可以使用方法3,因为这并不遥远。

    您应该分离类模板(Wektor)和参数类型推断:

    template <class T>
    struct WektorParamTraits {
      typedef T const& type;
    
      //or if you might have different types as getter return type and setter arg
      typedef T const& getterReturn;
      typedef T const& setterArg;
    };
    
    模板
    结构WektorParameters{
    typedef T const&type;
    //或者您可能有不同的类型,如getter返回类型和setter arg
    typedef T const&getterReturn;
    typedef T const&setterArg;
    };
    
    在这种情况下,T是getter/setter参数的“默认”类型。专门为你需要的任何类型。 现在,类定义应该如下所示:

    template<typename T,int Roz>
    class Wektor{
      T tab[Roz]; //make member variables private
    public:
      typename WektorParamTraits<T>::getterReturn get(int i) //const?
      {
        return tab[i];
      }
    
      void set(typename WektorParamTraits<T>::setterArg val,int i)
      {
        tab[i]=val;
      }
    };
    
    模板
    韦克托级{
    T tab[Roz];//使成员变量私有
    公众:
    typename WektorParamTraits::getterReturn get(int i)//const?
    {
    返回标签[i];
    }
    void set(类型名称WektorParamTraits::setterArg val,int i)
    {
    tab[i]=val;
    }
    };
    
    更新:如评论中所述,您可能需要为get和set定义其他实现,例如,如果您的返回类型是指针。有几种不同的方法可以做到这一点:

  • 在traits中定义函数,以便在
    选项卡[i]
    和参数/返回值之间正确转换
  • 如果只涉及指针和非指针,请提供两个版本的getter和setter,并使用
    std::enable_If
    std::is_pointer
    以及禁用其中一个所需的任何其他工具
  • 使用您在这里发布的简单类定义,并将其专门化为不使用常规引用的少数类型。任何进一步的功能都应该进入一个非专门化的子类

  • 方法2将非常冗长且难以阅读。方法1也会很冗长,因为除了数组定义之外,几乎所有的东西都会委托给traits类,所以也可以使用方法3,因为这并不遥远。

    我认为这个模板可以帮助您:

    template<typename T>
    class traits
    {
    public:
        typedef T * result;
    };
    
    template<>
    class traits<int>
    {
    public:
        typedef int result;
    };
    
    template<>
    class traits<double>
    {
    public:
        typedef double result;
    };
    
    
    traits<int>::result; // is int.
    traits<char>::result; // is char *.
    
    模板
    阶级特征
    {
    公众:
    typedef T*结果;
    };
    模板
    阶级特征
    {
    公众:
    输入结果;
    };
    模板
    阶级特征
    {
    公众:
    typedef双结果;
    };
    traits::result;//是int。
    traits::result;//是char*。
    
    我认为此模板可以帮助您:

    template<typename T>
    class traits
    {
    public:
        typedef T * result;
    };
    
    template<>
    class traits<int>
    {
    public:
        typedef int result;
    };
    
    template<>
    class traits<double>
    {
    public:
        typedef double result;
    };
    
    
    traits<int>::result; // is int.
    traits<char>::result; // is char *.
    
    模板
    阶级特征
    {
    公众:
    typedef T*结果;
    };
    模板
    阶级特征
    {
    公众:
    输入结果;
    };
    模板
    阶级特征
    {
    公众:
    typedef双结果;
    };
    traits::result;//是int。
    traits::result;//是char*。
    
    我不确定您想如何实现
    设置(T*,int)
    。但是对于
    get
    您可能想试试这个

    template<typename T, size_t Roz>
    class Wektor
    {
    public:
        template<typename U=T>
        typename std::enable_if<std::is_arithmetic<U>::value, U>::type 
            Get(size_t n)
        { 
            return tab[n];
        }
    
        template<typename U=T>
        typename std::enable_if<!std::is_arithmetic<U>::value, U*>::type 
            Get(size_t n)
        { 
            return &tab[n];
        }
    
        T tab[Roz];
    };
    
    模板
    韦克托级
    {
    公众:
    模板
    typename std::enable_if::type
    获取(大小\u t n)
    { 
    返回选项卡[n];
    }
    模板
    typename std::enable_if::value,U*>::type
    获取(大小\u t n)
    { 
    返回和制表符[n];
    }
    T标签[Roz];
    };
    
    我不确定您想如何实现
    设置(T*,int)
    。但是对于
    get
    您可能想试试这个

    template<typename T, size_t Roz>
    class Wektor
    {
    public:
        template<typename U=T>
        typename std::enable_if<std::is_arithmetic<U>::value, U>::type 
            Get(size_t n)
        { 
            return tab[n];
        }
    
        template<typename U=T>
        typename std::enable_if<!std::is_arithmetic<U>::value, U*>::type 
            Get(size_t n)
        { 
            return &tab[n];
        }
    
        T tab[Roz];
    };
    
    模板
    韦克托级
    {
    公众:
    模板
    typename std::enable_if::type
    获取(大小\u t n)
    { 
    返回选项卡[n];
    }
    模板
    typename std::enable_if::value,U*>::type
    获取(大小\u t n)
    { 
    返回和制表符[n];
    }
    T标签[Roz];
    };
    
    问题是当返回类型为指针时,您还需要不同的
    get
    set
    实现。问题是当返回类型为指针时,您还需要不同的
    get
    set
    实现。