模板专门化在链接时失败
Template specialization fails on linking
我有一个模板专门化的问题,我想了解。我正在使用Visual c++ 10.0(2010)。我有一个这样的类:
class VariableManager
{
public:
template<typename VarT>
VarT get(std::string const& name) const
{
// Some code...
}
// This method supposed to be fully evaluated, linkable method.
template<>
std::string get<std::string>(std::string const& name) const;
private:
std::map<std::string, boost::any> mVariables;
};
理论上,因为我专门化了"get"方法,链接器应该能够从目标文件中拾取。相反,如果将该方法放在源文件中,则会得到链接器未解析的引用错误:
template<>
std::string VariableManager::get<std::string>(std::string const& name) const
{
// Doing something...
}
如果我将这个方法作为内联方式放在头文件中,构建就会很顺利。我明白模板的作用是这样的:
template<typename VarT>
VarT get(std::string const& name) const;
应该放在头文件中,因为编译器不能根据调用代码对模板进行专门化,但在完全专门化的情况下,是类的实现实现了这一点,因此专门化的模板方法应该已经作为公共符号存在。有人能解释一下这个问题吗?
你的分析是正确的——一个显式专门化的函数模板,它的任何模板参数都用显式的值指定,从而提供了函数的完整定义。
如果你已经正确地将相应的包含显式专门化定义的.cpp
文件包含到你的项目中,那么vc++应该不会引发链接器错误。但是,为了符合标准,请允许我注意,您必须在封闭类的之外声明您的专门化。标准禁止在封闭类内部声明显式特化(并且其他编译器将拒绝您的代码)。因此,将头文件更改为像这样声明专门化,而不是
class VariableManager
{
public:
template<typename VarT>
VarT get(std::string const& name) const
{
// Some code...
}
private:
std::map<std::string, boost::any> mVariables;
};
// This method supposed to be fully evaluated, linkable method.
template<>
std::string VariableManager::get<std::string>(std::string const& name) const;
让我也注意到,你不能在你的类体内调用get<std::string>
。这是因为任何这样的调用都还没有看到显式专门化声明,因此会尝试从模板定义实例化函数。标准将这样的代码呈现为错误格式,而不需要进行诊断。
专门化模板不会强制编译器实例化它(我认为GCC会这样做);您仍然需要显式地告诉编译器实际实例化模板。可以通过显式模板实例化来实现。基本上,只需在源文件中添加以下内容:
template std::string VariableManager::get(const std::string& name) const;
以template<>
开头的方法仍然被认为是template
专门化方法。所以你必须把它放入头文件。
如果你想把它放到一个实现文件中,那么你必须重载它。
class VariableManager
{
//...
VarT get(std::string const& name) const
{}
std::string get(std::string const& name) const; //overloading not specialization
};
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- Netbeans 10:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- 链接 c++ 动态库一直失败
- 链接器命令失败,macOS 上的退出代码为 1(使用 -v 查看调用)
- CMake 错误:链接器命令失败,退出代码为 1 和 cpp.o 文件
- clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) - 体系结构的未定义符号 x86_64:
- 如何修复 clang: 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- 如何在 Linux 中构建共享库时使未定义引用的链接器失败
- mapreduce c编程与-fPIC链接失败,如何解决?
- Xcode:链接器命令失败,退出代码为 1(使用 -v 查看调用)[C++]
- 引用构造函数时链接失败
- 通过嵌入式 IWebBrowser2 控件中的链接打开 youtube 搜索失败
- Android NDK.Build命令失败.未定义的引用.clang++:错误:链接器命令失败,退出代码为1
- CMake链接库在Docker映像中失败
- 生成库失败:无法识别文件格式;作为链接器脚本处理
- 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用):在 Macbook 上
- JNI 不满意链接错误: 动态链接库 (DLL) 初始化例程失败
- C++ XCODE ld:找不到体系结构x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -
- Android Studio 链接器命令在包含 Boost 库时失败
- 链接 openGL 库失败,因为它无法打开 libgl.so ...但它就在那里