在模块文件中使用cout时非常奇怪的错误

发布于 2025-02-01 13:53:00 字数 4292 浏览 3 评论 0原文

抱歉,我无法制作MRE,在剪切代码中不会发生错误,但是我会尽可能删除代码。

main.cpp

#include <iostream>
#include "Functions.h"

using namespace std;

import TNode;

//USE C++20
int main()
{
    string line;
    cout << "Enter line:\n";
    getline(cin, line);
    TNode<char> head = stringToBinaryTree(line);
    line;
}

functions.h

#pragma once
#include <string>

using namespace std;

import TNode;

TNode<char> stringToBinaryTree(string s);

functions.cpp

#include "Functions.h"

using namespace std;

TNode<char> stringToBinaryTree(string s) {
    if (s.size() == 0) return TNode<char>();
    TNode<char> result(s[0]);
    for (size_t i = 1; i < s.length(); i++)
    {
        result.addChildren(s[i]);
    }
    return result;
}

tnode.ixx(cut)

module;

#include <iostream>

export module TNode;

export{
    template <class T> class TNode;
}

using namespace std;

template <class T>
class TNode {
    T value;
    TNode<T>* leftChildren;
    TNode<T>* rightChildren;
    TNode<T>* Parent;
public:
    TNode();
    TNode(const T value);
    TNode(TNode<T>& parent, const T value);
    TNode(const TNode<T>& copyTree);

    TNode<T>& operator=(const TNode<T>& source);

    TNode<T>* addChildren(T value);

    TNode<T>* left() const;
    TNode<T>* right() const;
    TNode<T>* parent() const;

    T getValue() const;
    void setValue(T value);
};

//then only the used methods and functions

template <class T> TNode<T>::TNode(TNode<T>& parentNode, const T value) {
    this->value = value;
    leftChildren = nullptr;
    rightChildren = nullptr;
    Parent = nullptr;
    if (parentNode.getValue() >= value) {
        if (parentNode.right() != nullptr) TNode(*parentNode.right(), value);
        else {
            parentNode.rightChildren = this;
            Parent = &parentNode;
        }
    }
    else {
        if (parentNode.left() != nullptr) TNode(*parentNode.left(), value);
        else {
            parentNode.leftChildren = this;
            Parent = &parentNode;
        }
    }
}

template <class T> TNode<T>* TNode<T>::addChildren(T value) {
    TNode<T>* children = new TNode<T>(*this, value);
    return children;
}

template <class T> void recursionCopy(TNode<T>* dest, const TNode<T>* source) {
    dest->addChildren(source->getValue());
    //cout << "Added " << source->getValue() << "to destination"; //if uncomment this happens error C2995 and C2572
    //if (dest->parent()) cout << " with parrent " << dest->parent() << "\n"; //but if uncomment this while still have prev line uncommented its LNK2005 and LNK1169 errors now
    //else cout << "\n";
    if (source->left()) {
        //cout << "Goind to left with value " << source->left()->getValue() << "\n";
        recursionCopy(dest, source->left());
    }
    if (source->right()) {
        //cout << "Goind to right with value " << source->right()->getValue() << "\n";
        recursionCopy(dest, source->right());
    }       
}

template <class T> TNode<T>::TNode(const TNode<T>& copyTree) {
    value = copyTree.value;
    recursionCopy(this, &copyTree);
}

template <class T> T TNode<T>::getValue() const {
    return value;
}

template <class T> TNode<T>* TNode<T>::parent() const {
    return Parent;
}

问题发生在recursioncopy()函数中。

当我不输入cout代码时,没有汇编或链接错误。

当我删除使用getValue()的第一行时,编译器会发疯,并说operator!=模板已经定义。为什么?我没有定义或使用运算符!=,但它给了我这个错误,来自&lt; iosfwd&gt; file。

但是,有趣的部分是当我将第二行与parent()删除时,它会导致具有8个函数的链接器错误,但是出于某种原因,在function.obj中引起了链接错误。这里的链接器错误之一:

“ public:void __thiscall std :: basic_ostream&lt; char,struct std :: char_traits&lt; char&gt;&gt;&gt; :: _ osfx(void)(_osfx@?_osfx@? @std @@ qaexxz)“ functions.obj

已经定义

Sorry, I couldn't make an MRE, the error doesn't happen in the cut code, but I will cut the code as much as possible.

main.cpp

#include <iostream>
#include "Functions.h"

using namespace std;

import TNode;

//USE C++20
int main()
{
    string line;
    cout << "Enter line:\n";
    getline(cin, line);
    TNode<char> head = stringToBinaryTree(line);
    line;
}

Functions.h

#pragma once
#include <string>

using namespace std;

import TNode;

TNode<char> stringToBinaryTree(string s);

Functions.cpp

#include "Functions.h"

using namespace std;

TNode<char> stringToBinaryTree(string s) {
    if (s.size() == 0) return TNode<char>();
    TNode<char> result(s[0]);
    for (size_t i = 1; i < s.length(); i++)
    {
        result.addChildren(s[i]);
    }
    return result;
}

TNode.ixx (cut)

module;

#include <iostream>

export module TNode;

export{
    template <class T> class TNode;
}

using namespace std;

template <class T>
class TNode {
    T value;
    TNode<T>* leftChildren;
    TNode<T>* rightChildren;
    TNode<T>* Parent;
public:
    TNode();
    TNode(const T value);
    TNode(TNode<T>& parent, const T value);
    TNode(const TNode<T>& copyTree);

    TNode<T>& operator=(const TNode<T>& source);

    TNode<T>* addChildren(T value);

    TNode<T>* left() const;
    TNode<T>* right() const;
    TNode<T>* parent() const;

    T getValue() const;
    void setValue(T value);
};

//then only the used methods and functions

template <class T> TNode<T>::TNode(TNode<T>& parentNode, const T value) {
    this->value = value;
    leftChildren = nullptr;
    rightChildren = nullptr;
    Parent = nullptr;
    if (parentNode.getValue() >= value) {
        if (parentNode.right() != nullptr) TNode(*parentNode.right(), value);
        else {
            parentNode.rightChildren = this;
            Parent = &parentNode;
        }
    }
    else {
        if (parentNode.left() != nullptr) TNode(*parentNode.left(), value);
        else {
            parentNode.leftChildren = this;
            Parent = &parentNode;
        }
    }
}

template <class T> TNode<T>* TNode<T>::addChildren(T value) {
    TNode<T>* children = new TNode<T>(*this, value);
    return children;
}

template <class T> void recursionCopy(TNode<T>* dest, const TNode<T>* source) {
    dest->addChildren(source->getValue());
    //cout << "Added " << source->getValue() << "to destination"; //if uncomment this happens error C2995 and C2572
    //if (dest->parent()) cout << " with parrent " << dest->parent() << "\n"; //but if uncomment this while still have prev line uncommented its LNK2005 and LNK1169 errors now
    //else cout << "\n";
    if (source->left()) {
        //cout << "Goind to left with value " << source->left()->getValue() << "\n";
        recursionCopy(dest, source->left());
    }
    if (source->right()) {
        //cout << "Goind to right with value " << source->right()->getValue() << "\n";
        recursionCopy(dest, source->right());
    }       
}

template <class T> TNode<T>::TNode(const TNode<T>& copyTree) {
    value = copyTree.value;
    recursionCopy(this, ©Tree);
}

template <class T> T TNode<T>::getValue() const {
    return value;
}

template <class T> TNode<T>* TNode<T>::parent() const {
    return Parent;
}

The problem happens in the recursionCopy() function.

When I don't uncomment the cout code, there are no compilation or link errors.

When I uncomment the first line where I used getValue(), the compiler is getting MAD and saying the operator!= template is already defined. Why? I am not defining or using operator!=, but it gives me this error from the <iosfwd> file.

But the interesting part comes when I uncomment the second line with parent(), it causes linker errors with 8 functions, but in Functions.obj for some reason. Here one of the linker errors:

"public: void __thiscall std::basic_ostream<char,struct std::char_traits<char> >::_Osfx(void)" (?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEXXZ)" already defined in Functions.obj

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文