【问题标题】:Library with multiple template definitions具有多个模板定义的库
【发布时间】:2012-04-24 20:39:07
【问题描述】:

我正在学习如何使用 Visual Studio 2010 创建库。所以为了测试多个符号,我刚刚写了 -

add.cpp

template <typename T>
T fooBar(T a1, T a2)
{
  return (a1+a2);
}

减去.cpp

template <typename T>
T fooBar(T a1, T a2)
{
  return (a1-a2);
}

据我了解,模板是一个编译时概念。只是为了测试该工具在函数/函数模板之间的行为,我写了上面的内容。它成功地创建了.lib,即使在为功能模板设置的最高级别也没有任何警告。但是,在正常功能的情况下,它会发出警告。

add.obj : 警告 LNK4006: "int __cdecl fooBar(int,int)" (?fooBar@@YAHHH@Z) 已经在 subtract.obj 中定义;第二个定义被忽略

add.obj:警告 LNK4221:未找到公共符号;存档成员将无法访问

为什么该工具对函数和函数模板的行为不同?

【问题讨论】:

  • 你试过检查你出去的.lib吗?
  • 你从哪里引用这些函数?令我担心的是,您将这些定义在 .cpp 文件中,而不是在 .h.hxx 文件中。可能在没有任何警告/错误的情况下创建了 .lib,因为您实际上根本没有编译它们。
  • 您是否尝试过实例化模板函数,例如,通过编写如下内容: int a;诠释 b; int c = fooBar(a,b); ?否则编译器将永远不会实例化模板并且永远不必在两者之间进行选择。
  • @BjörnPollex 是的。每个源文件都有两行特定的名称修改完成。我不确定要检查多远才能更具体。
  • @Mahesh,我会根据我所说的在下面发布一个答案。

标签: c++ visual-studio-2010 function templates static-libraries


【解决方案1】:

由于它们是模板函数,因此在您实际实例化模板函数之前,它们本身不会被编译。

例如,我只是将以下代码放入我的一个 .cpp 文件中而不使用它,并且 .cpp 文件的编译运行良好(尽管有明显的语法错误):

template <typename J>
int foobar(J junk)
{
#pragma message("Compiling foobar")
     ppp = 35;

     return 0;
}

直到我尝试编译它(即创建它的编译器实例):

int main(void)
{
     double x;
     int y = foobar(x);
     return 0;
}

我是否收到编译错误。

: error C2065: 'ppp' : undeclared identifier  

你自己试试这个,它可能会帮助你解释你所看到的(至少在你提到的第一种情况下没有错误。)

【讨论】:

  • 如果没有模板实例化,我可以认为模板根本不会出现警告吗?
  • 它根本没有编译,所以没有重复的符号等。你不会收到任何警告或错误或任何东西。如果您在 foobar 函数中添加 #pragma message("Compiling foobar"),您将准确地看到它的编译时间。
  • 我想补充一点,函数模板允许在多个翻译单元中定义。但是,如果定义不相同,那么它就是未定义的行为,这里就是这种情况。
猜你喜欢
  • 1970-01-01
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多