我正在尝试构建类型模板的向量,但不断出现错误
template<class T>
struct s{
T val;
public:
s(T a)
{
val = a;
};
friend ostream& operator<<(ostream& os, const T& a);
};
template <typename T>
ostream& operator<< (ostream& os, const T& a){
return os << a.val;
}
int main()
{
s <double> names(4) ;
s <int> figure(7);
s <string> word();
s <vector<int>*> arrays();
cout << names << endl;
cout << figure << endl;
cout << arrays << endl;
return 0;
}
我一直收到同样的错误 -
request for member 'val' in 'a', which is of non-class type 's<std::vector<int>*>()'|
非常感谢任何建议
答案 0 :(得分:2)
s <vector<int>*> arrays();
这不会实例化一个对象,它会声明一个返回s<vector<int>*>
的函数,因此:
cout << arrays << endl;
尝试通过实例化模板operator<<
:
template <typename T>
ostream& operator<< (ostream& os, const T& a){
return os << a.val;
}
使用:
T = s<vector<int>*>(*)();
因此,指向函数a
的指针没有触发错误的.val
字段。
答案 1 :(得分:2)
s <vector<int>*> arrays();
声明一个名为arrays
的函数,不带参数并返回s<vector<int>*>
。删除冗余括号或将其替换为{}
for C ++ 11。当然,你的s
不支持默认构造,所以你需要给它一个默认构造函数 - 这可以像给构造函数一个默认参数一样简单:
s(T a = T())
{
val = a;
}
并且最好使用成员初始化列表而不是赋值并使用const ref而不是value,因为T
可能很大:
s(const T& a = T()) : val(a) { }
在C ++ 11中,您应该按值并将移动 a
改为val
:
s(T a = T()) : val(std::move(a)) { }
此外,
template <typename T>
ostream& operator<< (ostream& os, const T& a){
return os << a.val;
}
会匹配太阳下的一切。最好只匹配s
:
template <typename T>
ostream& operator<< (ostream& os, const s<T>& a){
return os << a.val;
}
最后,
friend ostream& operator<<(ostream& os, const T& a);
befriends(并声明)一个简单的函数而不是函数模板。要与上面修改的模板operator <<
成为朋友:
template <typename U>
friend ostream& operator<<(ostream& os, const s<U>& a);
甚至更好,删除模板运算符并定义内联的friend函数(在类定义中):
friend ostream& operator<<(ostream& os, const s<T>& a){
return os << a.val;
}
这更紧凑,并且还限制了与operator <<
的匹配版本的友谊,而不是模板的所有实例化。
答案 2 :(得分:1)
整个问题是这个
ClassName InstanceName();
不是使用默认构造函数创建ClassName
的实例,而是声明一个函数。为了做你想做的事(我假设是用默认构造函数创建实例),使用语法
ClassName InstanceName;
因此,为了解决您的错误,请更改
s <string> word();
s <vector<int>*> arrays();
到
s <string> word;
s <vector<int>*> arrays;
并向您的班级s
添加default constructor。