如何在调用模板显式实例化时打开自动匹配

How can I turn on the auto matching when invoking the template explicit instantiation?

本文关键字:实例化 调用      更新时间:2023-10-16

我有两个模板类,Leaf<T>是从Base<T>派生出来的,然后我开发了一个模板函数,它使用Base<T>的引用作为其参数。并在其源文件中设置该函数的定义和实例化。

一旦我尝试将Leaf<T>作为该函数的参数传递,就会出现问题。编译器尝试查找带有Leaf<T>的符号,而无需像以前那样使用自动约定。

// foo.h
#ifndef __FOO_H_INCLUDED__
#define __FOO_H_INCLUDED__
#include <base.h>
template <typename T>
void Foo(T &value);
#endif // __FOO_H_INCLUDED__

// foo.cpp
#include <foo.h>
#include <iostream>
template <typename T>
void Foo(T &value)
{
    std::cout<<value.getValue()<<std::endl;
}
template void Foo(MyBase<int> &value);

// main.cpp
#include <leaf.h>
#include <foo.h>
int main()
{
    int i = 20;
    MyLeaf<int> leaf;
    leaf.setValue(i);
    Foo(leaf);
}

上面的代码片段将在链接中引发"未定义的引用"异常。重构调用Foo<MyBase<int> >(leaf)将解决问题,但这不是我想要的。显式实例化所有潜在的派生类型也是不可能的,因为无法知道它们有多少。

那么有没有一种方法可以让链接器用基本类型识别我的符号,而不是找到精确的符号并抛出错误呢?

在一个翻译单元中添加显式模板实例化必须与显式模板实例化声明配对,以确保编译器不会尝试执行隐式实例化。否则,程序格式不正确。

除此之外,除了Foo<MyLeaf<int>>设置方式之外,您不能让模板参数推导任何其他内容。但是通过一些调整,我们可以让它工作。在标题中:

template <typename T>
void Foo(MyBase<T> &value);
extern template void Foo(MyBase<int> &value);

在您的实现文件中:

template <typename T>
void Foo(MyBase<T> &value)
{
    std::cout<<value.getValue()<<std::endl;
}
template void Foo(MyBase<int> &value);

现在,扣除规则和重载分辨率应该与函数正确匹配。我们所做的是转移负担。现在该函数始终需要从 MyBase 实例化的类。由于从MyLeaf实例化的每个类也派生自从MyBase实例化的一个类,你可以看到它的去向。我们满足参数的模板要求,只是让它从中推断出T