[英]C++: Template class binary operator overloading - seg fault?
The following describe the example I have which works: 以下描述了我有工作的示例:
header
: header
:
const size_t N = 10;
// template<size_t N>
class SymbolicMonomial {
public:
int powers[N];
int constant;
SymbolicMonomial() {
for (int i = 0; i < N; i++) {
this->powers[i] = 0;
}
this->constant = 1;
}
SymbolicMonomial(int variable): SymbolicMonomial(){
this->powers[variable] = 1;
}
static SymbolicMonomial as_monomial(int value){
auto result = SymbolicMonomial();
result.constant = value;
return result;
}
bool is_constant(){
for(int i=0;i<N;i++){
if(this->powers[i] > 0){
return false;
}
}
return true;
}
};
// template<size_t N>
std::ostream &operator<<(std::ostream &out, const SymbolicMonomial value){
out << value.constant << "(";
for(int i=0;i<N-1;i++){
out << value.powers[i] << ", ";
}
out << value.powers[N-1] << ")";
}
// template<size_t N>
SymbolicMonomial operator*(SymbolicMonomial lhs, SymbolicMonomial rhs) {
SymbolicMonomial result = SymbolicMonomial();
for (int i = 0; i < N; i++) {
result.powers[i] = lhs.powers[i] + rhs.powers[i];
}
result.constant = lhs.constant * rhs.constant;
return result;
}
The main.cpp
: main.cpp
:
int main(int argc, char *argv[])
{
auto t_a = symbolic::SymbolicMonomial(2);
auto t_b = symbolic::SymbolicMonomial(1);
auto t_c = t_b*t_a*t_a;
std::cout << t_c << std::endl;
return 0;
}
And everything is fine. 一切都很好。 However, I wanted to change the whole thing to have a template argument
<N>
instead of a constant. 但是,我想将整个内容更改为具有模板参数
<N>
而不是常量。 Thus this is the templated code: header.h
: 因此,这是模板代码:
header.h
:
template<const size_t N>
class SymbolicMonomial {
public:
int powers[N];
int constant;
SymbolicMonomial() {
for (int i = 0; i < N; i++) {
this->powers[i] = 0;
}
this->constant = 1;
}
SymbolicMonomial(int variable): SymbolicMonomial(){
this->powers[variable] = 1;
}
static SymbolicMonomial as_monomial(int value){
auto result = SymbolicMonomial<N>();
result.constant = value;
return result;
}
bool is_constant(){
for(int i=0;i<N;i++){
if(this->powers[i] > 0){
return false;
}
}
return true;
}
};
template<const size_t N>
std::ostream &operator<<(std::ostream &out, const SymbolicMonomial<N> value){
out << value.constant << "(";
for(int i=0;i<N-1;i++){
out << value.powers[i] << ", ";
}
out << value.powers[N-1] << ")";
}
template<const size_t N>
SymbolicMonomial<N> operator*(SymbolicMonomial<N> lhs, SymbolicMonomial<N> rhs) {
SymbolicMonomial<N> result = SymbolicMonomial<N>();
for (int i = 0; i < N; i++) {
result.powers[i] = lhs.powers[i] + rhs.powers[i];
}
result.constant = lhs.constant * rhs.constant;
return result;
}
And main.cpp
: 和
main.cpp
:
int main(int argc, char *argv[])
{
auto t_a = symbolic::SymbolicMonomial<10>(2);
auto t_b = symbolic::SymbolicMonomial<10>(1);
auto t_c = t_b*t_a*t_a;
std::cout << t_c << std::endl;
return 0;
}
Now the non template version works as expected, however the templated one fails with code 139 (SEGFAULT). 现在,非模板版本可以按预期工作,但是带模板的版本失败,代码为139(SEGFAULT)。 Firstly, I do not understand why the code fails if someone can explain and secondly how to fix it?
首先,如果有人可以解释,我不理解为什么代码会失败,其次,如何解决?
std::ostream &operator<<(std::ostream &out, const SymbolicMonomial<N> value)
isn't returning a value. std::ostream &operator<<(std::ostream &out, const SymbolicMonomial<N> value)
没有返回值。 For me, in Visual Studio, that resulted in a compile error. 对我来说,在Visual Studio中,这导致了编译错误。 Adding
return out;
增加
return out;
to the end of the function lead to the code working without an ACCESS_VIOLATION (Windows flavor of a SEGFAULT). 到函数结尾将导致代码在没有ACCESS_VIOLATION(SEGFAULT的Windows风格)的情况下工作。
All of your bound-checking looks correct, so, if I had to guess, I'd say that your compiler is ignoring the missing return, and you're entering a spooky space known as undefined behavior when you work with a return value that was never actually set. 您所有的边界检查看起来都是正确的,因此,如果我不得不猜测,我会说您的编译器将忽略缺失的返回值,并且当您使用返回值时,您正在进入一个怪异的空间,称为未定义行为 。从未真正设置过。
Assuming you're using GCC, you can set -Werror=return-type
to throw compile errors when you make these kinds of mistakes. 假设您使用的是GCC,则可以设置
-Werror=return-type
在发生此类错误时引发编译错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.