由于嵌套在模板化类中的类内的“<<”重载而导致链接错误 [duplicate]

Linking error due to `<<` overload inside class nested within templated class [duplicate]

提问人:Gregor Hartl Watters 提问时间:11/10/2023 更新时间:11/10/2023 访问量:44

问:

我正在尝试重载流插入运算符以允许将我的类的实例打印到 .<<gml::tensor<T>::shapestdout

为了重现问题的根源,我尽可能地减少了我的代码:

#include <iostream>
#include <concepts>

namespace gml {
    template <typename T>
    concept Numeric = requires (T value) {
        T{1};
    };
    template <Numeric T>
    class tensor;
    template <Numeric T>
    std::ostream &operator<<(std::ostream&, const typename tensor<T>::shape&);
    template <Numeric T>
    class tensor {
    public:
        class shape {
        public:
            shape() = default;
            friend std::ostream &operator<<(std::ostream&, const shape&);
        };
        tensor() {
            std::cout << "tensor ctor" << std::endl;
        }
    };
    template <Numeric T>
    std::ostream &operator<<(std::ostream &out, const typename tensor<T>::shape &s) {
        return out << "PRINTING AT LAST!!!\n" << std::endl;
    }
}

int main() {
    gml::tensor<long double>::shape s;
    std::cout << s << std::endl;
    return 0;
}

我得到的链接器错误是:

Undefined symbols for architecture arm64:
  "gml::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, gml::tensor<long double>::shape const&)", referenced from:
      _main in test-eaec7e.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我开始认为我想做的事情是不可能的。

我可以将重载定义为成员函数,但在此之前,我想知道是否可以执行任何操作来允许在 之外定义该函数。<<gml::tensor<T>::shape

注意:删除 和 forward 声明没有任何区别。tensoroperator<<

C++ 模板 内部类 friend

评论

3赞 HolyBlackCat 11/10/2023
你是一个非模板函数,但你的实际是一个模板。我会将 的定义移到类主体中。或者你可以整个模板。(或者事先声明模板及其特定专业化。friendoperator<<operator<<friendfriend
0赞 Gregor Hartl Watters 11/10/2023
@HolyBlackCat非常感谢。当你说“整个模板”时,你的意思是声明为一个模板化的朋友函数吗?我也尝试过专门化它,但无济于事。我很感激你的帮助。friendoperator<<gml::tensor<T>::shape
1赞 n. m. could be an AI 11/10/2023
您是否看到任何编译器警告?至少启用 -Wall -Wextra。
2赞 HolyBlackCat 11/10/2023
“与整个模板成为朋友”——我认为这将是在班级内部。template <Numeric T> friend std::ostream &operator<<(std::ostream&, const typename tensor<T>::shape&);
0赞 Gregor Hartl Watters 11/10/2023
@HolyBlackCat非常感谢,我以前试过,但它也没有用。我只在类中定义函数:(我非常感谢您的帮助!

答: 暂无答案