简体   繁体   English

C ++:模板类二进制运算符重载-seg错误?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM