为什么C ++函数模板代码无法编译?

时间:2013-11-10 06:06:32

标签: c++ function templates

我在网上搜索过,但找不到问题的答案>为什么C ++模板代码无法编译?一旦我删除return语句之前的最后一行,它就会按预期编译并运行。

我使用g ++版本4.3.4。我将非常感谢专家的帮助。

此致 maicah

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <stdint.h>
#include <boost/lexical_cast.hpp>

void mult(int* ptr)
{
 std::cout << "void mult(" << *ptr  << "): line: " << __LINE__  << ", function: "<<    __FUNCTION__ << std::endl;
}

template <typename T>
void multIndirect(T* x)
{
    std::cout << "void mult(" << *x  << "): line: " << __LINE__  << ", function: "<< __FUNCTION__ << std::endl;
}

void apply(void (*funcPtr)(int*), int* pVal)
{
    std::cout << "apply(" << boost::lexical_cast<std::string>((uintptr_t) funcPtr)  << ", "  << *pVal << "): line:"  << __LINE__  << ", function: " << __FUNCTION__ << std::endl;
    funcPtr(pVal);
}

template <typename Func, typename T>
void applyIndirect(Func funcPtr, T* x)
{
  std::cout << "apply(" << boost::lexical_cast<std::string>((uintptr_t) funcPtr)  << ", "  << *x << "): line:"  << __LINE__  << ", function: " << __FUNCTION__ << std::endl;
  funcPtr(x);
}


int main(void) {

int y = 300;

mult(&y);
apply(mult, &y);
apply(multIndirect, &y);
    applyIndirect(multIndirect, &y);
return EXIT_SUCCESS;
}

我收到编译错误:

CPPTemplate.cpp: In function int main():
CPPTemplate.cpp:47: error: no matching function for call to applyIndirect(<unresolved         overloaded function type>, int*)
make: *** [CPPTemplate.o] Error 1

2 个答案:

答案 0 :(得分:2)

您必须指定要间接应用的 multIndirect<T>

applyIndirect(multIndirect<int>, &y);

如果使用apply,则无需指定类型,因为编译器会推断出正确的类型:

void apply(void (*funcPtr)(int*), int* pVal);
//         ^^^^^^^^^^^^^^^^^^^^^

答案 1 :(得分:1)

您希望编译器如何推断Func的模板参数applyIndirect的实际值,并因此从此调用中推导T的模板参数multIndirect

applyIndirect(multIndirect, &y);

在此致电multIndirect中,T可以是doublecharSomeOtherType或其他任何内容。您使Func参数成为完全 free 类型,并且您提供的编译器绝对没有办法确定它应该是什么类型。这是导致错误的原因。

鉴于您声明applyIndirect,要使其编译,您必须明确告诉编译器TmultIndirect的值

applyIndirect(multIndirect<int>, &y);

现在知道multIndirect<int>的类型,编译器将能够找出Func应该是什么。或者,您也可以在Func

中明确告诉编译器applyIndirect的值
applyIndirect<void (int *)>(multIndirect, &y);

知道Func的值,编译器将能够找出T应该是multIndirect的内容。

但是,查看applyIndirect的正文,您似乎希望funcPtr使用类型x的参数T *。这意味着funcPtr的类型实际上不应该是自由类型。它应该实际上取决于T。你为什么要把它变成一个免费的呢?为什么要引入额外的模板参数Func?那个目的是什么?

您应该简单地将applyIndirect声明为

,而不是引入额外的模板参数
template <typename T>
void applyIndirect(void funcPtr(T *), T *x)
{
  funcPtr(x);
}

这与apply的声明方式一致。

现在编译器将理解x类型与所需类型funcPtr之间的链接。有了这样的声明,你就可以打电话了

applyIndirect(multIndirect, &y);

编译器将根据&y T int的类型来确定funcPtrvoid (int *)。反过来,这意味着multIndirect的类型为T == int。这将使{{1}}实例化{{1}}。