链接错误:模板化友元运算符重载

发布于 2024-09-30 14:11:36 字数 2279 浏览 3 评论 0原文

我遇到了一个奇怪的链接错误。我按照此处提供的说明来避免此类问题,但我不知道如何拆分标头和实现文件。

这是我的测试文件:

#include <cargo.h>
#include <iostream>
#include <string>

using namespace std;
using namespace dom;

int main()
{
    dom::cargo<string> text("Hello, World!");

    cout << text << endl;

    return 0;
}

测试中包含的 class Cargo 头文件:

#ifndef CARGO_H
#define CARGO_H 1

#include "node.h"

#include <iostream>

namespace dom
{
    template <typename Type> class cargo;

    template <typename Type>
    std::ostream& operator<<(std::ostream&, const dom::cargo<Type>&);

    template <typename Type>
    class cargo
        : public dom::node
    {
        Type value;

    public:
        cargo()
            : value()
        { }

        cargo(Type value)
            : value(value)
        { }

        friend std::ostream& operator<< <>(std::ostream&, const dom::cargo<Type>&);
    };
}

#endif // !CARGO_H

及其实现:

#include "cargo.h"

template <typename Type>
std::ostream& operator<< (std::ostream& ostream, dom::cargo<Type>& cargo)
{
    return (ostream << cargo.value);
}

我正在使用 CMake 来编译并将其全部链接在一起。 我得到的链接错误是关于对 operator << 的未定义引用:

Scanning dependencies of target test
[100%] Building CXX object Tests/CMakeFiles/test.dir/test0.c++.o
Linking CXX executable test
CMakeFiles/test.dir/test0.c++.o: In function `main':
test0.c++:(.text+0x9b): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& dom::operator<< <std::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::basic_ostream<char, std::char_traits<char> >&, dom::cargo<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)'
collect2: ld returned 1 exit status
make[2]: *** [Tests/test] Error 1
make[1]: *** [Tests/CMakeFiles/test.dir/all] Error 2
make: *** [all] Error 2

我做错了什么?请帮我!

I am having a strange linking error. I followed instructions presented here to avoid this kind of problems, but I can't figure out how to split headers and implementation files.

Here's my test file:

#include <cargo.h>
#include <iostream>
#include <string>

using namespace std;
using namespace dom;

int main()
{
    dom::cargo<string> text("Hello, World!");

    cout << text << endl;

    return 0;
}

Header file for class cargo included in the test:

#ifndef CARGO_H
#define CARGO_H 1

#include "node.h"

#include <iostream>

namespace dom
{
    template <typename Type> class cargo;

    template <typename Type>
    std::ostream& operator<<(std::ostream&, const dom::cargo<Type>&);

    template <typename Type>
    class cargo
        : public dom::node
    {
        Type value;

    public:
        cargo()
            : value()
        { }

        cargo(Type value)
            : value(value)
        { }

        friend std::ostream& operator<< <>(std::ostream&, const dom::cargo<Type>&);
    };
}

#endif // !CARGO_H

And its implementation:

#include "cargo.h"

template <typename Type>
std::ostream& operator<< (std::ostream& ostream, dom::cargo<Type>& cargo)
{
    return (ostream << cargo.value);
}

I'm using CMake to compile and link it all togather.
The linking error I get is about undefined reference to operator <<:

Scanning dependencies of target test
[100%] Building CXX object Tests/CMakeFiles/test.dir/test0.c++.o
Linking CXX executable test
CMakeFiles/test.dir/test0.c++.o: In function `main':
test0.c++:(.text+0x9b): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& dom::operator<< <std::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::basic_ostream<char, std::char_traits<char> >&, dom::cargo<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)'
collect2: ld returned 1 exit status
make[2]: *** [Tests/test] Error 1
make[1]: *** [Tests/CMakeFiles/test.dir/all] Error 2
make: *** [all] Error 2

What am I doing wrong? Please help me!

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遗忘曾经 2024-10-07 14:11:36

(成员)函数模板不是函数;除非您实例化它们,否则链接器看不到它们。源文件是单独编译的,因此如果您将(成员)函数模板放入一个源文件中并且没有显式实例化它,链接器将看不到它。

因此,在您的情况下,函数模板尚未转换为 cargo.o 中的函数,因此链接器会报告错误,因为 main.o 依赖于它。您需要将模板放在头文件中,或者在 cargo.cpp 中显式实例化它。

(Member) function templates are not functions; the linker doesn't see them unless you instantiate them. Source files are compiled separately, so if you put a (member) function template in one source file and don't explicitly instantiate it, the linker won't see it.

So in your case, the function template has not been turned into a function in cargo.o, so the linker reports an error because main.o depends on it. You need to put the template in the header file, or explicitly instantiate it in cargo.cpp.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文