我有一个非常简单的问题。
template<class Type, class Type2>
void function(Type & a, Type2 & b)
{
cout << a << " " << b << endl;
}
template<class Type, class Type2>
int main()
{
function(1, 2.0);
}
我使用的是Visual Studio 2012,红色下划线没有任何内容。我尝试编译,但它给了&#34; 1未解析的外部&#34;错误。
答案 0 :(得分:4)
代码存在两个问题。
首先,main
函数不应该是模板。您只需删除template
行
template<class Type, class Type2>
int main()
其次,您将临时传递为non-const
引用。这是not allowed。您可以尝试更改添加const
的模板函数签名:
void function(const Type & a, const Type2 & b)
(好吧,VS 有时候允许non-const
引用临时绑定,虽然它不应该。但也许不是你的情况。)
此外,function
可能会与std::function
发生冲突。考虑重命名。
答案 1 :(得分:2)
main
函数无法模板化:
int main()
{
function(1, 2.0);
}
答案 2 :(得分:0)
您无法模拟main()
函数,因为它是程序的入口点。但是,如果要模板化另一个函数,语法非常简单:
#include <iostream>
template<class Type, class Type2>
void function(Type a, Type2 b)
{
std::cout << a << " " << b << std::endl;
}
int main()
{
function(1, 1);
function(1, 2.0);
}
答案 3 :(得分:0)
虽然你已经得到了许多包含正确信息的答案,但是没有一个答案解决了我看起来像底层问题的问题:你的程序如何编译/链接,但是IDE没有用红色下划线表示错误?
答案很简单:您编写的代码不包含任何实际错误。它只是不完整。
尽管如此,这可能并没有多大帮助。要理解它,您可能需要更多地了解开发工具如何协同工作以生成程序。
尽管您可能还没有使用过大型项目(如果有的话),除了最小的程序之外,将代码分解为多个文件是相当典型的。在这种情况下,这些文件中的一个(且仅一个)将包含main
函数。其余包含其他代码 - 函数定义,类定义等。其中每一个都可以独立编译(假设代码编写正确)。然后,当它们全部被编译时,链接器会运行以将这些部分组合成一个完整的程序。
目前看来,您的代码正在正确编译。只有当它到达那个连接阶段时才会崩溃。如上所述,原因很简单:因为您的程序不完整。具体要求是(§3.6.1/ 1):
程序应包含一个名为main的全局函数,它是程序的指定开始。
现在,您可能会(非常正确地)指出您的代码 包含您打算用作程序开头的main
。这个问题(正如其他人指出的那样,但没有一个直接说明)是,虽然你已经定义了名为main
的某事,但你所定义的是不是一个功能 - 它是一个功能模板。函数模板本身不是函数 - 它是一段代码,可以在实例化时生成模板。
实例化类模板时,实例化非常明显:
std::vector<int> data;
对于函数模板,实例化通常不太明显 - 您定义了一个函数模板,然后调用就像是一个函数一样。编译器根据您传递的参数类型,选择要使用的模板参数。
虽然有一个限制:要弄清楚函数调用中传递的参数类型,编译器必须“看到”函数模板和(源代码到)调用该函数模板。然后它可以查看传递的参数类型,将它们替换为模板参数,并根据它们为这些参数创建该函数模板的实例化。
编译器需要查看函数模板本身和对该函数模板的调用,将两者放在一起并为该调用创建实际函数。将模板作为函数调用实际上涉及三个步骤:
现在关键点:要调用模板函数,这三个步骤必须按顺序进行。首先,它必须同时查看调用和模板,然后它实例化模板,然后它可以生成代码来调用从模板实例化的函数。不同的调用可能导致模板以不同方式实例化,而(反过来)需要生成不同的代码来调用生成的函数。
调用main
的代码不允许这组步骤。它被预先编译成一个库,因此在编译时,编译器不能考虑任何函数模板 - 它们根本就不存在于那个时间/地点。