C++不会使用T = Hoge&这样的实例化模板。

一个最小的例子:

  • hoge.h:
    #include<cstdio>
    class Hoge
    {
      public:
        Hoge()
          : hoge(0)
        {
        }
        ~Hoge()
        {
        }
    
        int hoge;
        void print() { printf("%d\n", hoge); }
    };
    
    template<typename T>
    void f(T a);
    
  • hoge.cpp:
    #include "hoge.h"
    template<typename T>
    void f(T a)
    {
      a.print();
    }
    
    template void f<Hoge &>(Hoge &a);
    
  • main.cpp:
    #include "hoge.h"
    int main(void)
    {
      Hoge h;
      f(h);
      return 0;
    }
    

  • 我用g++ -std=c++11 main.cpp hoge.cpp编译了它们。但是它给出了一个链接器错误:
    Undefined symbols for architecture x86_64:
      "void f<Hoge>(Hoge)", referenced from:
          _main in aa-e35088.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    接下来,我将f(h)中的main.cpp更改为f<Hoge &>,错误消失了。

    为什么在第一种情况下不调用f<Hoge &>(Hoge &)
    对于这种情况,我可以通过每次键入f<Hoge &>来避免错误。但是,当涉及到重载运算符时,它是无法完成的。

    请告诉我如何解决此错误。

    最佳答案

    编译器将尝试推断出最简单的模板T。在这里,T=Hoge很好,因此编译器不会尝试更详细的形式。

    但是,您可以清楚地说明您的意图。请尝试以下方法:

    template<typename T>
    void f(T& a);
    
    T仍将推导为Hoge,但是您的函数f将获得引用。
    这使读者可以直接在f原型(prototype)中清楚地看到这一点。

    当涉及到模板参数推导时,在编译器框架下会发生很多规则。当我声明编译器推断出最简单的T时,我确实在偷工减料。这是一个可靠的来源:cppreference

    关于c++ - 我们如何用引用类型实例化模板函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48161480/

    10-10 16:19