3

让我们假设我们有一个函数模板,它在 cpp 文件中借助显式实例化实现,如下所示:

函数.h

template<typename T> void function(T val);

函数.cpp

#include "function.h"

template<typename T> void function(T val) { /* do something */ }

template void function<double>(double val);

我们现在可以在包含function.h的主文件中调用该函数,如下所示:

double val = 1.0;

function(val);

让我们进一步假设我们有一个这样实现的类:

数据.h

class Data
    {
    private:
        double mVal;

    public:
        Data(double val) { mVal = val; }

        operator double () { return mVal; }
    };

以下代码导致链接器错误 LNK2019: unresolved external (Visual Studio 2010):

Data a(1.0);

function(a);

我们可以使用以下表达式之一来为function ()

function<double>(a);
function(double(a));
...

但是为什么不能只调用function(a)?是否存在任何其他解决方案来实现这一点,而无需显式实例化具有数据类型的function()

4

2 回答 2

6

为什么不能打电话function(a)

这是。你在叫它。但请记住,它function被声明为:

template<typename T> void function(T val);

所以模板推演会推演function<Data>。模板推导不知道代码中的其他地方只有一个定义function<double>——它只是进行推导。并且function<Data>没有定义,因此无法链接。

在我看来,自己执行显式转换(function<double>(a)或者function(static_cast<double>(a)))将是最好的解决方案。明确的很好。您还可以编写一个单独的函数,其中包含您实际支持的所有重载,然后转发到函数模板:

void fwd_function(double v) { function(v); }
void fwd_function(foo v) { function(v); }
void fwd_function(bar v) { function(v); }

fwd_function(a); // now we call function<double> because fwd_function(double )
                 // is the what we're actually calling
于 2016-05-19T16:55:34.750 回答
1

不可能调用function(a),因为 thenT的类型是Data,而不是double,即使它有那个转换运算符。而且因为您没有在cpp文件中明确定义它,所以会出现链接器错误。

以下是您可以使用的一些解决方案:

//Call operator double() explicitly 
function(a.operator double());

//Specify T
function<double>(a);

//Casting
function(static_cast<double>(a));
于 2016-05-19T16:56:24.753 回答