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

Why does the C++ function template code not compile?

本文关键字:编译 代码 C++ 函数模板 为什么      更新时间:2023-10-16

我在网上搜索过,但我找不到问题的答案> 为什么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
您必须

指定要间接应用哪个multIndirect<T>

applyIndirect(multIndirect<int>, &y);

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

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

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

applyIndirect(multIndirect, &y);

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

给定你的applyIndirect声明,要使其编译,你必须明确地告诉编译器T的值multIndirect

applyIndirect(multIndirect<int>, &y);

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

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

了解Func的值,编译器将能够弄清楚multIndirect应该是什么T

但是,查看applyIndirect的主体,您似乎想将funcPtr与类型为 T * 的参数x一起使用。这意味着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 .