我在网上搜索过,但找不到问题的答案>为什么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
答案 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
可以是double
或char
或SomeOtherType
或其他任何内容。您使Func
参数成为完全 free 类型,并且您提供的编译器绝对没有办法确定它应该是什么类型。这是导致错误的原因。
鉴于您声明applyIndirect
,要使其编译,您必须明确告诉编译器T
中multIndirect
的值
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
的类型来确定funcPtr
是void (int *)
。反过来,这意味着multIndirect
的类型为T == int
。这将使{{1}}实例化{{1}}。