为什么它期待Struct1以及如何格式化它以便我可以修改任何结构中的属性?
我有一个模板类,我用来修改包含相同属性名称的3个结构中的数据,它们碰巧使用不同的数据类型。
我正在尝试在我的模板类中使用模板方法,所有内容似乎都按照我预期的方式在各种实例化时使用模板类。
GenericClass<Struct1> inventory[1000];
GenericClass<Struct2> machines[1000];
GenericClass<Struct3> physicalStructures[1000];
(是的,我知道向量存在,一起播放,我尽可能包含尽可能少的代码)这就是说,当我尝试更改结构的一个属性时,我得到一个错误,指出它正在期待struct,而不是采用我提供的任何数据类型。
Main.cpp:39:28: error: no viable conversion from 'int' to 'Struct1'
inventory[0].setIdentifier(1);
我已经检查了这3个引用(以及其他一些引用),但它们似乎并不像我在其中任何一个那样做。 How to define template function within template class in *.inl file
Template class with template function
https://isocpp.org/wiki/faq/templates
以下是我的代码示例。
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;
}
返回方法也不起作用,我预计它们都会因为类似的原因而失败。
同样,为什么它期待Struct1以及如何格式化它以便我可以修改任何结构中的属性?
答案 0 :(得分:2)
为什么期待Struct1
因为这是被告知要使用的类型。
给出模板:
template<typename Type>
class GenericClass
{
private:
Type Identifier;
public:
void setIdentifier(Type Param);
Type getIdentifier();
};
类型为Struct1
(GenericClass<Struct1>
)的实例化会生成以下实现:
// Just for illustration
class GenericClassStruct1
{
private:
Struct1 Identifier;
public:
void setIdentifier(Struct1 Param);
Struct1 getIdentifier();
};
上述类已将所有Type
替换为Struct1
。现在,应该很容易理解为什么调用setIdentifier
期望Struct1
而不是int
。
如何格式化,以便我可以修改任何结构中的属性
有多种方法可以做到这一点。什么是“正确”的方式将取决于您的问题的限制,但以下示例显示了一种方式。
#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
答案 1 :(得分:1)
模板GenericClass
定义了一系列类。 GenericClass
的每个专精都有自己的setIdentifier()
专一。因此,GenericClass<Struct1>
只有一个setIdentifer()
接受Struct1
,但没有setIdentifier()
接受int
(或任何其他类型)。在使用inventory[0].setIdentifier(1)
中,inventory[0]
的类型为GenericClass<Struct1>
,其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);
}
答案 2 :(得分:-1)
Identifier
是指GenericRecord::Identifier
,其中是你的一个结构,而不是 成员名为Identifier
。同样,Type
是结构类型,而不是其Identifier
成员的类型。因此,您的方法永远不会使用您尝试包装的“属性”。
简单的解决方案涉及属性类型的另一个模板参数:
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;}
};