在 C++ 中将范数定义为 vector class 的成员函数
Define norm as member function of vector class in C++
我正在尝试用 C++ 编写自己的向量 class。特别是,我想将范数实现为成员函数。以下 classic 代码片段是我所做的:
#include <iostream>
#include <cmath>
template <typename T>
class vector{
private:
T* elem;
std::size_t _size;
public:
vector(const std::size_t size) : elem{new T[size]}, _size{size} {}
~vector(){ delete[] elem;}
std::size_t size() const { return _size;}
T& operator[](std::size_t i){ return elem[i];}
const T& operator[](std::size_t i) const{ return elem[i];}
friend T norm();
};
template <typename T>
T vector::norm(){
T sum{0};
for (auto i=0u;i<_size;++i){
sum+=elem[i];
}
return std::sqrt(sum);
}
int main(){
vector<double> v{10};
for (auto i=0u;i<v.size();++i){
v[i] = i;
}
std::cout << v.norm() <<std::endl;
return 0;
}
显然,我可以在 class 内部定义函数 norm
,但我想在外部定义它,因为原则上其中一个成员函数的主体可能有几行那么长。
一旦我尝试编译,编译器说:
- 'template<class T> class vector' 不使用模板参数
_size
、elem
未在范围 中声明
- 'class vector<double>' 没有名为 'norm'
的成员
但我不明白哪里出了问题,也不知道如何解决!特别是最后一点我不明白:我明确声明 norm()
为成员函数!我应该如何更改我的代码?
您将 norm()
声明为 friend
函数,因此它实际上不是 vector
class 本身的成员。您告诉编译器某些外部 non-member 函数 T norm()
是 vector
的 friend 以便它可以访问 vector
的私有成员。但是你实际上并没有定义这样一个 T norm()
函数!
将 norm()
作为成员实现的正确方法,在 class 声明之外定义,应该是这样的:
template <typename T>
class vector{
...
public:
...
T norm(); // <-- remove 'friend'!
};
template <typename T>
T vector<T>::norm(){ // <-- note the extra <T>!
T sum{0};
for (auto i = 0u; i < _size; ++i){
sum += elem[i];
}
return std::sqrt(sum);
}
旁注:
您可以考虑使用 SFINAE 省略 norm()
的声明+定义 T
类型 std::sqrt()
不支持的类型(non-integers/floating-point 类型,例如字符串等)。
此外,您的 vector
class 未实现 Rule of 3/5/0 以正确管理其内部数组。您需要向其添加适当的 copy/move 构造函数和 copy/move 赋值运算符。
我正在尝试用 C++ 编写自己的向量 class。特别是,我想将范数实现为成员函数。以下 classic 代码片段是我所做的:
#include <iostream>
#include <cmath>
template <typename T>
class vector{
private:
T* elem;
std::size_t _size;
public:
vector(const std::size_t size) : elem{new T[size]}, _size{size} {}
~vector(){ delete[] elem;}
std::size_t size() const { return _size;}
T& operator[](std::size_t i){ return elem[i];}
const T& operator[](std::size_t i) const{ return elem[i];}
friend T norm();
};
template <typename T>
T vector::norm(){
T sum{0};
for (auto i=0u;i<_size;++i){
sum+=elem[i];
}
return std::sqrt(sum);
}
int main(){
vector<double> v{10};
for (auto i=0u;i<v.size();++i){
v[i] = i;
}
std::cout << v.norm() <<std::endl;
return 0;
}
显然,我可以在 class 内部定义函数 norm
,但我想在外部定义它,因为原则上其中一个成员函数的主体可能有几行那么长。
一旦我尝试编译,编译器说:
- 'template<class T> class vector' 不使用模板参数
_size
、elem
未在范围 中声明
- 'class vector<double>' 没有名为 'norm' 的成员
但我不明白哪里出了问题,也不知道如何解决!特别是最后一点我不明白:我明确声明 norm()
为成员函数!我应该如何更改我的代码?
您将 norm()
声明为 friend
函数,因此它实际上不是 vector
class 本身的成员。您告诉编译器某些外部 non-member 函数 T norm()
是 vector
的 friend 以便它可以访问 vector
的私有成员。但是你实际上并没有定义这样一个 T norm()
函数!
将 norm()
作为成员实现的正确方法,在 class 声明之外定义,应该是这样的:
template <typename T>
class vector{
...
public:
...
T norm(); // <-- remove 'friend'!
};
template <typename T>
T vector<T>::norm(){ // <-- note the extra <T>!
T sum{0};
for (auto i = 0u; i < _size; ++i){
sum += elem[i];
}
return std::sqrt(sum);
}
旁注:
您可以考虑使用 SFINAE 省略 norm()
的声明+定义 T
类型 std::sqrt()
不支持的类型(non-integers/floating-point 类型,例如字符串等)。
此外,您的 vector
class 未实现 Rule of 3/5/0 以正确管理其内部数组。您需要向其添加适当的 copy/move 构造函数和 copy/move 赋值运算符。