C++ 在模板类中使用模板方法

C++ 在模板类中使用模板方法,c++,c++11,templates,C++,C++11,Templates,为什么它需要Struct1?我如何格式化它以便可以修改任何struct中的属性 我有一个模板类,用于修改包含相同属性名的3个结构中的数据,它们恰好使用不同的数据类型 我试图在我的模板类中使用一个模板方法,在各种实例化中,模板类的一切似乎都像我期望的那样工作 GenericClass<Struct1> inventory[1000]; GenericClass<Struct2> machines[1000]; GenericClass<Struct3> phys

为什么它需要Struct1?我如何格式化它以便可以修改任何struct中的属性

我有一个模板类,用于修改包含相同属性名的3个结构中的数据,它们恰好使用不同的数据类型

我试图在我的模板类中使用一个模板方法,在各种实例化中,模板类的一切似乎都像我期望的那样工作

GenericClass<Struct1> inventory[1000];
GenericClass<Struct2> machines[1000];
GenericClass<Struct3> physicalStructures[1000];
我已经检查了这3个参考资料(还有一些),但它们似乎都不像我在其中的任何一个。

这是我的代码示例

template <class Type>
class GenericClass
{ 
private:
  Type Identifier;
public:
  void setIdentifier(Type Param);
  Type getIdentifier();
};


/* Struct prototypes
************************/
struct Struct1
{
private:
  int Identifier;
  string Description;
  float Value;
}

struct Struct2
{
private:
  long int Identifier;
  string Description;
  float Value;
};

struct Struct3
{
private:
 string Identifier;
 string Description;
 double Value;
};


int main()
{
  GenericRecord<Struct1> inventory[1000];
  GenericRecord<Struct2> machines[1000];
  GenericRecord<Struct3> physicalStructures[1000];
  inventory[0].setIdentifier(1);
}


template <class Type>
void GenericRecord<Type>::setIdentifier(Type Param)
{
  Identifier = Param;
}
template <class Type>
Type GenericRecord<Type>::getIdentifier()
{
  return Identifier;
}
模板
类泛型类
{ 
私人:
类型标识符;
公众:
void setIdentifier(类型Param);
键入getIdentifier();
};
/*结构原型
************************/
结构1
{
私人:
int标识符;
字符串描述;
浮动值;
}
结构2
{
私人:
长整数标识符;
字符串描述;
浮动值;
};
结构3
{
私人:
字符串标识符;
字符串描述;
双重价值;
};
int main()
{
通用记录清单[1000];
通用记录机[1000];
通用记录物理结构[1000];
清单[0]。设置标识符(1);
}
模板
void GenericRecord::setIdentifier(类型参数)
{
标识符=参数;
}
模板
类型GenericRecord::getIdentifier()
{
返回标识符;
}
return方法也不起作用,我希望它们都因为类似的原因而失败


同样,为什么它需要Struct1,我如何格式化它以便修改任何结构中的属性?

在有问题的方法中,Identifier指的是
genericord::Identifier
,它是您的结构之一,而不是名为
Identifier的成员。类似地,
Type
是结构类型,而不是其
标识符的类型。因此,您的方法从不使用您试图包装的“属性”

简单解决方案涉及属性类型的另一个模板参数:

template<class T,class P>
class GenericRecord {
  T wrapped;      // avoid confusing reuse of "Identifier"
public:
  void setIdentifier(P p) {wrapped.Identifier=p;}
  P getIdentifier() const {return wrapped.Identifier;}
};
模板
类GenericRecord{
T wrapped;//避免混淆“标识符”的重用
公众:
void setIdentifier(P){wrapped.Identifier=P;}
P getIdentifier()常量{return wrapped.Identifier;}
};

模板化的
GenericClass
定义了一系列类。
GenericClass
的每个专门化都有自己的
setIdentifier()
专门化。因此
GenericClass
有一个接受
Struct1
setIdentifier()
,但没有接受
int
(或任何其他类型)的
setIdentifier()
。在用法
inventory[0].setIdentifier(1)
中,
inventory[0]
属于
GenericClass
类型,其
setIdentifier()
成员函数可以接受
Struct1
,但不能接受
int
。因此出现了错误消息

如果我明白你想做什么(我不确定-只是根据你的非工作代码猜测),你需要做如下事情

template<class T> class Struct
{
   public:
      void SetIdentifier(const T &id) {Identifier = id;};
      T getIdentifier() const {return Identifier;};
    private:
       T Identifier;
       std::string Description;
       float Value;
};

template <class Type>
class GenericClass
{ 
   private:
       Struct<Type> data;
   public:
      void setIdentifier(Type Param) {data.setIdentifier(Param);};
      Type getIdentifier() const {return data.getIdentifier();};
};

int main()
{
      GenericClass<int> inventory[1000];
      inventory[0].setIdentifier(1);
}
模板类结构
{
公众:
void SetIdentifier(const T&id){Identifier=id;};
T getIdentifier()常量{返回标识符;};
私人:
T标识符;
std::字符串描述;
浮动值;
};
模板
类泛型类
{ 
私人:
结构数据;
公众:
void setIdentifier(Type Param){data.setIdentifier(Param);};
键入getIdentifier()const{return data.getIdentifier();};
};
int main()
{
普通类库存[1000];
清单[0]。设置标识符(1);
}
为什么是1

因为那是它被告知要使用的类型

给定模板:

template<typename Type>
class GenericClass
{
private:
    Type Identifier;

public:
    void setIdentifier(Type Param);
    Type getIdentifier();
};
上述类已将所有出现的
Type
替换为
Struct1
。现在,应该很容易理解为什么调用
setIdentifier
需要
Struct1
而不是
int

如何格式化它,以便可以修改任何结构中的属性

实现这一点的方法不止一种。什么是“正确”的方法取决于问题的约束条件,但下面的示例显示了一种方法

例子


inventory[0]
的类型为
GenericClass
,因此
inventory[0]。setIdentifier()
被指定为需要类型为
Struct1
的参数。您的代码正在传递一个
int
GenericClass
是一个模板类,没错,但这并不意味着
GenericClass::setIdentifier()
可以接受任何类型的参数-它只接受
Struct1
类型的参数。有意义的是,关于构造解决方案,我需要知道什么?您可以修改
Struct1
,2和3?在这种情况下,我只能修改类。
template<typename Type>
class GenericClass
{
private:
    Type Identifier;

public:
    void setIdentifier(Type Param);
    Type getIdentifier();
};
// Just for illustration
class GenericClassStruct1
{
private:
    Struct1 Identifier;

public:
    void setIdentifier(Struct1 Param);
    Struct1 getIdentifier();
};
#include <iostream>

// Declared but not defined, specializations will provide definitions
template<typename T>
struct GenericTypeTraits;

template<typename T>
class Generic
{
public:
    using IdType = typename GenericTypeTraits<T>::IdType;

    void setIdentifier(IdType id)
    {
        mType.mIdentifier = id;
    }

    IdType getIdentifier() const
    {
        return mType.mIdentifier;
    }

private:
    T mType;
};

class Type1
{
public:
    int mIdentifier;
};

template<>
struct GenericTypeTraits<Type1>
{
    using IdType = int;
};

class Type2
{
public:
    std::string mIdentifier;
};

template<>
struct GenericTypeTraits<Type2>
{
    using IdType = std::string;
};

int main()
{
    Generic<Type1> t1[5];
    t1[0].setIdentifier(3);
    std::cout << t1[0].getIdentifier() << "\n";

    Generic<Type2> t2[5];
    t2[0].setIdentifier("3");
    std::cout << t2[0].getIdentifier() << "\n";

    return 0;
}
3
3