【问题标题】:C++ specialized method templates produce multiple definition errorsC++ 专用方法模板产生多个定义错误
【发布时间】:2025-12-08 12:35:01
【问题描述】:

我正在使用 C++ 98。我正在编写一个 JSON 对象包装器。对于所有普通数字,它们可以使用相同的函数,但对于浮点数和双精度数,我需要一个单独的函数。字符串也一样。我使用模板和专业化编写了这个,它编译得很好,但是当我构建我的整个项目时,我得到了大约 10 亿个关于多个定义的错误。我假设我没有正确专业化。我能够在类对象本身中有和没有这些定义的情况下编译这个文件,所以我什至不知道是否需要这些定义。

class Object {
    public:
        template <class T>
        bool Set(std::string key, T value);
        // having these defined or not doesn't seem to matter
        bool Set(std::string key, double value);
        bool Set(std::string key, float value);
        bool Set(std::string key, std::string value);
};


template <class T>
bool Object::Set(std::string key, T value){
}

template <>
bool Object::Set<double>(std::string key, double value){
}


template <>
bool Object::Set<float>(std::string key, float value){
}

template <>
bool Object::Set<std::string>(std::string key, std::string value){
}

我如何正确地专门化这些模板以使编译器/链接器不适合?

【问题讨论】:

  • 我使用的是 C++ 98,伙计,我们得让你摆脱那些东西。
  • 完全同意@user4581301 这是你的实际限制吗?如果没有,请至少使用 c++11,即使现在已经有十年了。
  • 哈哈,当然这是一个实际的约束。在这件事上我别无选择。打电话给 WindRiver,问他们为什么花了 2 年才达到 C++11..
  • 很公平,只是检查一下。通常人们最终会使用旧版本,因为他们有旧教科书或其他东西。
  • 说实话,就在几年前,我把我的公司从 GCC 3.3 中拖了出来,一路上都在尖叫。新来的孩子们正在享受std::thread 和 lambdas 之类的东西。很高兴听到“天哪!这就像 Python 一样简单!”。即使他们在撒谎。

标签: c++ c++98


【解决方案1】:

如果您在头文件中定义类外部模板的成员函数的特化,则需要像这样使特化inline

template <> 
inline bool Object::Set<double>(std::string key, double value){
}

template <>
inline bool Object::Set<float>(std::string key, float value){
}

template <>
inline bool Object::Set<std::string>(std::string key, std::string value){
}

【讨论】:

  • 这仅适用于专业化吗?
  • 是的,因为特化不再依赖于模板参数,所以它们会为每个包含在其中的头文件实例化。
  • 哎呀。这将破坏我的编译时间,并且我正在接近编译文件大小限制..
  • 如果这是一个问题,那么有办法解决这个问题。例如在标头中声明专业化,并在 .cpp 中实现它们应该会有所帮助(我认为)。
  • 那太神奇了。我会试试的。不过我还是有点担心。这个问题有相互矛盾的答案,说模板总是内联...*.com/questions/10535667/…