调用实例化函数期间的链接器错误

Linker error during calling instantiated function

以下代码产生链接器错误:

#include <iostream>

template<class T>
class A
{
public:
    void foo(int);
    template<class V> void foo(V v){ std::cout << "foo" << std::endl; }
};

A<int> a;
int main(){ a.foo(3); } //Here is the error.

DEMO

但是下面的代码工作正常:

#include <iostream>

template<class T>
class A
{
public:
    template<class V> void foo(V v){ std::cout << "foo" << std::endl; }
};

A<int> a;
int main(){ a.foo(3); } //OK, call to foo<int>

DEMO

为什么第一个示例没有导致成员的隐式实例化,而第二个示例却有。

好吧,我认为在第一种情况下,编译器不知道您需要哪个 foo 函数。 foo(3) 可以匹配 void foo(int);template<class V> void foo(V v)。要更正此问题,请在 main 中明确告诉您需要模板版本:

 a.foo<int>(3); // or just  a.foo<>(3);

在第二种情况下,您只有一个 foo 函数。所以没有问题。

在所有其他条件相同的情况下,非模板函数在重载决策中优先于函数模板。在您的第一个示例中,在 A<int>.foo(3); 中,候选者是非模板 void foo(int) 和模板 template<class V> void foo(V) with V = int。替换后,签名相同,因此 [over.match.best]/p1.6 中的决胜局适用:

a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then

  • [several inapplicable bullets omitted]
  • F1 is not a function template specialization and F2 is a function template specialization
  • [inapplicable bullet omitted]

因此,A<int>.foo(3); 明确解析为非模板 foo(),您没有为其提供定义,因此出现链接器错误。