函数模板语法错误

时间:2015-08-28 03:47:28

标签: c++ templates

我是模板新手。在浏览其中一个教程时,我发现了以下声明:

我们有以下功能模板:

template<class T1, class T2>
void PrintNumbers(const T1& t1Data, const T2& t2Data)
{}

以这种方式调用函数:

PrintNumbers<double, double>(10, 100);

会产生以下模板功能:

void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data)
{}

但是,如果我在我的程序中尝试完全相同的东西它不起作用并抛出很多错误:

template<class T1, class T2>
void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data)
{}
int main()
{
    PrintNumbers<double, double>(10, 100);   
    return 0;
}

但如果我使用以下功能模板而不是上面的功能模板,那么它可以工作:

template<class T1, class T2>
void PrintNumbers(const T1& t1Data, const T2& t2Data)
{}

我试图理解这个特定概念的方式有问题吗? 如果是这样,void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data)到底意味着什么以及如何使用它(在哪种情况下)?

2 个答案:

答案 0 :(得分:1)

是的,我认为你不是正确理解模板。所以当你有一个模板化的函数时,你需要有这样的定义

template <typename T1, typename T2>
void PrintNumbers(const T1& t1Data, const T2& t2Data) {}

并称之为

PrintNumbers(100.0, 100.0)

这将解析上述模板以调用看起来像这样的函数

void PrintNumbers(const double& t1Data, const double& t2Data);

您在第一种情况下尝试的内容将被称为explicit template specialization。而且你会这样做

template <typename T1, typename T2>
void PrintNumbers(const T1& t1Data, const T2& t2Data) {}

template <>
void PrintNumbers<double, double> (const double& t1Data, const double& t2Data) {/*Something else here */}

然后当您进行下面的函数调用(1)将转到专用函数时,(2)和(3)将转到第一个非专业函数。

PrintNumbers(10.0, 10.0);     // (1)
PrintNumbers("some", "word"); // (2)
PrintNumbers(std::vector<int>(), std::vector<int>()); // (3)

C ++中还有一些称为部分模板特化和非类型模板的机制。我可以详细介绍,但这足以填写一篇大博文,然后填写一些。你应该谷歌他们了解更多细节。它们非常有用,聪明的C ++程序员使用它们来编译在其他语言中无法实现的编译时间扣除。

答案 1 :(得分:1)

所以我认为这是理解模板语法细微差别的问题。

所有这些都与编译器的观点非常不同:

  • 模板
  • 模板专业化
  • 模板实例化

对于结构,函数,typedef等,所有这些都可能发生。

写作时

template<class T1, class T2>
void PrintNumbers(const T1& t1Data, const T2& t2Data)
{}

声明模板函数。在此之后,您可以使用符号PrintNumbers作为具有两个参数的函数,它将实例化模板,创建具有两个参数的相应函数。

如果您只想要特定版本,则根本不能使用模板

void PrintNumber(const double &, const double &)
{}

那没关系。

当你写:

void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data)
{}

这实际上没有任何意义,将被编译器拒绝。当您将模板参数放在像这样的声明符之后,它应该是模板特化。然而,

  • 为此您必须使用关键字template,即使是template<> void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data) {}

  • 这样的空参数列表
  • 必须有模板的PRIOR声明。您只能对已存在的模板进行专门化,编译器不会仅为您介绍模板。我不能告诉你为什么,这就是它的工作原理。

通常,您应该使用模板的方式是

  • 首先使用template< foo, bar, baz > my_function(A a, B b, ...) {}
  • 声明“完整”模板
  • (可选)添加一些部分特化,注意不要进行模糊的部分特化: template<foo, bar> my_function<foo, bar, bar::baz_type>(A a, B b, ...) {}
  • 现在根据需要实例化模板。