【问题标题】:Undefined reference to template operator with definition in same header file在同一头文件中定义的对模板运算符的未定义引用
【发布时间】:2020-08-28 15:03:51
【问题描述】:

在尝试使用我编写的模板化运算符时,我收到了来自 clang++ 的链接器错误。

错误是:

main.cpp:(.text+0xfe): undefined reference to `operator<<(std::ostream&, schematic<130ul, 128ul, 130ul> const&)'
main.cpp:(.text+0x28c): undefined reference to `operator<<(std::ostream&, schematic<130ul, 1ul, 130ul> const&)'

现在在我继续之前或者您将其标记为重复之前:我知道您不能将模板定义放在单独的 .cpp 文件中,而我没有这样做。运算符的定义是在一个单独的头文件中,该文件包含在其声明中,如this answer 中所述。由于它仍然给我链接器错误,我在这里问。

代码

main.cpp

// includes

int main(int argc, char const* argv[])
{
    // ...

    switch (/* call */)
    {
        case /* one */:
            fout << mapArtFlat(/* ctor params */).exportScematic();
        break;
        case /* another */:
            fout << mapArtStaircase(/* ctor params */).exportSchematic();
        break;
    }
    return 0;
}

原理图.h

#ifndef SCHEMATIC_H
#define SCHEMATIC_H

// includes

template <std::size_t W, std::size_t H, std::size_t L>
class schematic
{
    friend std::ostream& operator<<(std::ostream&, const schematic<W,H,L>&);

    // class things
};

// output operator
template <std::size_t W, std::size_t H, std::size_t L>
std::ostream& operator<<(std::ostream&, const schematic<W,H,L>&);

// ...

#include "schematic_cpp.h"
#endif

schematic_cpp.h

// ...

// output operator
template <std::size_t W, std::size_t H, std::size_t L>
std::ostream& operator<<(std::ostream& lhs, const schematic<W,H,L>& rhs)
{
    // lot of code involving external libraries and processing data from the object
}

// ...

我尝试过的事情

  • 注释掉原理图.h 中的operator&lt;&lt; 声明
  • 使operator&lt;&lt; 内联

【问题讨论】:

    标签: c++ templates linker-errors


    【解决方案1】:

    您的示例大部分都有效,无法重现您遇到的错误。还是找到了应该改的地方。

    首先,您不能在尚未声明的函数上声明友谊。您需要将模板operator&lt;&lt; 声明放在类定义之前。但是,当您尝试这样做时,您意识到您需要声明原理图类,因为它是函数类型的一部分。转发声明该类,你应该没问题:

    template <std::size_t W, std::size_t H, std::size_t L>
    class schematic;
    
    template <std::size_t W, std::size_t H, std::size_t L>
    std::ostream& operator<<(std::ostream&, const schematic<W,H,L>&);
    
    template <std::size_t W, std::size_t H, std::size_t L>
    class schematic {
        // ... stuff ...
    };
    

    其次,您需要明确声明要声明为友元的函数的模板参数(或声明您与每个模板参数的每个函数都是友元)。你可以这样做:

    template <std::size_t W, std::size_t H, std::size_t L>
    class schematic
    {
        friend std::ostream& operator<<<W,H,L>(std::ostream&, const schematic<W,H,L>&);
        // ... class stuff ...
    };
    

    如果解决这些问题并不能解决您的问题,请尝试发布完整的minimal reproducible example 您遇到的问题。您的链接问题可能与模板实例化被丢弃有关,因为您在实现中做了一些事情。

    【讨论】:

      猜你喜欢
      • 2012-06-24
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-10
      • 1970-01-01
      相关资源
      最近更新 更多