繁体   English   中英

C ++解析未解析的外部

[英]C++ Templating Unresolved Externals

我有一个非常简单的问题。

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,红色下划线没有。 我尝试编译,但它给出“ 1无法解析的外部”错误。

代码有两个问题。

首先, main功能不应该是模板。 您可以删除template

template<class Type, class Type2>
int main()

其次,您将临时对象作为non-const引用传递。 这是不允许的 您可以尝试更改模板函数签名,添加const

void function(const Type & a, const Type2 & b)

(好吧,VS 有时允许non-const引用临时绑定,尽管它不允许这样做。但是无论如何在您的情况下都是不允许的。)


另外, function可能与std::function冲突。 考虑重命名。

main功能无法建立范本:

int main()
{
    function(1, 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);
}

尽管您已经获得了许多包含正确信息的答案,但是这些答案都没有解决我所认为的基本问题:您的程序如何不进行编译/链接,而IDE却不对其中的任何内容进行下划线红色表示错误?

答案很简单:您编写的代码不包含任何实际错误。 只是不完整。

但这本身可能并没有多大帮助。 要理解它,您可能需要更多地了解您的开发工具如何协同工作以生成程序。

尽管您可能还没有(如果没有)处理较大的项目,但是除了最小的程序以外,将代码分解成多个文件是相当典型的。 在这种情况下,这些文件中的一个(只有一个)将包含一个main功能。 其余的包含其他代码-函数定义,类定义等。 每个代码都可以独立于其他代码进行编译(当然,假设代码编写正确)。 然后,当它们全部编译好之后,链接器就会运行以将这些片段组合成一个完整的程序。

就目前而言,您的代码正在正确编译。 只有到了链接阶段,事情才瓦解。 如上所述,这样做的原因很简单:因为您的程序不完整。 具体要求是(§3.6.1/ 1):

程序应包含一个称为main的全局功能,这是程序的指定启动位置。

现在,您可能会通过(相当正确地)指出您的代码确实包含打算用作程序启动的main代码来做出反应。 这样的问题(正如其他人指出的那样,但是没有一个人直接指出)是,尽管您定义了一个名为main 东西 ,但您定义的不是函数,而是函数模板 函数模板不是函数本身,而是一段代码,可以在实例化它时生成一个模板。

实例化模板时,实例化是相当明显的:

std::vector<int> data;

对于函数模板,实例化通常不那么可见-定义一个函数模板,然后像调用一个函数一样进行调用。 编译器会根据您传递的参数类型来选择要使用的模板参数。

但是有一个限制:要弄清楚函数调用中传递的参数的类型,编译器必须“看到”函数模板对该函数模板的(源代码)调用。 然后,它可以查看要传递的参数的类型,将其替换为模板参数,然后基于这些参数为这些参数创建该函数模板的实例化。

编译器需要同时查看功能模板本身对该功能模板的调用,以将二者放在一起并为该调用创建一个实际函数。 将该模板作为函数调用实际上涉及三个步骤:

  1. 检查调用和模板的源代码
  2. 根据要传递的参数的类型实例化模板
  3. 生成代码以为要传递的类型调用生成的函数

现在到了关键点:要调用模板函数,这三个步骤必须按此顺序进行 首先,它必须同时查看调用和模板, 然后实例化模板, 然后可以生成代码以调用从模板实例化的函数。 不同的调用可能导致模板的实例化不同,从而(进而)需要生成不同的代码来调用生成的函数。

调用main的代码不允许执行这些步骤。 它已经预编译到库中,因此在编译时,编译器无法考虑任何功能模板-在那个时间/地点它们根本不存在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM