0

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

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

问候, 迈卡

#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
4

2 回答 2

2

您必须指定 multIndirect<T>间接应用的内容:

applyIndirect(multIndirect<int>, &y);

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

void apply(void (*funcPtr)(int*), int* pVal);
//         ^^^^^^^^^^^^^^^^^^^^^
于 2013-11-10T06:12:16.363 回答
1

您如何期望编译器从该调用中推断出模板参数的实际值,从而推断出模板参数的Func实际applyIndirectTmultIndirect

applyIndirect(multIndirect, &y);

?

在这个电话multIndirect中,T可能是doublecharSomeOtherType或其他任何东西。您使Func参数成为完全自由的类型,并且您为编译器提供了绝对无法确定它应该是什么类型的方法。这就是导致错误的原因。

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

applyIndirect(multIndirect<int>, &y);

现在知道multIndirect<int>编译器的类型将能够弄清楚Func应该是什么。或者,或者,您可以明确告诉编译器Funcin的值applyIndirect

applyIndirect<void (int *)>(multIndirect, &y);

知道Func编译器的值将能够弄清楚TformultIndirect应该是什么。

但是,查看您的主体,您applyIndirect似乎想与typefuncPtr的参数一起使用。这意味着 type of并不真正应该是自由类型。它应该实际上取决于. 那你为什么把它变成自由类型呢?你为什么要引入那个额外的模板参数?这样做的目的是什么?xT *funcPtrTFunc

而不是引入额外的模板参数,您应该简单地将您的声明applyIndirect

template <typename T>
void applyIndirect(void funcPtr(T *), T *x)
{
  funcPtr(x);
}

这将立即与apply声明的方式一致。

现在编译器将了解 的类型x和所需类型之间的联系funcPtr。有了这样的声明,您将可以致电

applyIndirect(multIndirect, &y);

&y编译器会从that的类型T中找出int. 反过来,这将意味着 的类型funcPtrvoid (int *)。这将使它实例化为multIndirect.T == int

于 2013-11-10T06:49:45.143 回答