尽管有很多关于类似主题的问题,但我找不到解决我问题的问题。
我正在使用Visual Studio 2013 Community Edition。我有一个包含两个项目的解决方案。一个项目编译为静态库,另一个项目是应用程序。应用程序依赖于静态库,它编译并运行良好。
链接器忽略一个类(.cpp / .h对),特别是Ref,(在底部列出的源)。从我的编译输出中,ref.cpp在namespace.cpp之前编译。 namespace.cpp间接包含ref.h,可能导致链接器的先进先出行为忽略Ref ?
我有一个运算符重载<<在ref.cpp和ref.h中。为什么它似乎被忽略了?
warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library [...]Omni\Core\ref.obj Core
ref.h
#ifndef REF_H
#define REF_H
#include <memory>
#include <ostream>
namespace Omni
{
template<typename T>
using Ref = std::shared_ptr<T>;
}
template<typename T>
std::ostream & operator<<(std::ostream & s, const Omni::Ref<T> type);
#endif // REF_H
(我知道using namespace Omni;
排除了Omni::
的需要,但在调试中我喜欢双重确认。)
ref.cpp
#include "ref.h"
using namespace Omni;
template<typename T>
std::ostream & operator<<(std::ostream & s, const Omni::Ref<T> value)
{
return s << *value;
}
答案 0 :(得分:2)
啊我能看出你做了什么。您认为ref.cpp中的函数定义实际上不是函数定义(即它不生成代码)。它只是一个模板函数定义。
为了使此模板生成代码,您必须实际引用模板函数的具体示例。
但是当然在你的ref.cpp中没有这样做,所以当编译ref.cpp时,没有实例化operator<<(std::ostream&, const Omni::Ref<T>)
的具体例子。
当您的客户端代码在operator<<
上为任何Omni::Ref<T>
调用T
时,它会很好地生成调用站点代码,因为有一个模板原型,但实际上没有信息创建函数的实现 - 这是在ref.cpp中,客户端代码无法使用。
解决方案: 将模板函数的定义放在头文件中。