仅具有静态方法的模板类使用 .cpp 文件实现给出错误

Posted

技术标签:

【中文标题】仅具有静态方法的模板类使用 .cpp 文件实现给出错误【英文标题】:Template class with only static methods Implementation using .cpp file giving error 【发布时间】:2020-12-23 02:32:38 【问题描述】:

我正在尝试在 C++ 中实现一个类,其中包含我可能需要在不同类层次结构中使用的大部分函数(该项目有多个不同的继承树)。

在阅读了Stack overflow、Why can templates only be implemented in the header file? 上此类实现的多个答案并从多个答案中获得建议后,我决定使用 .h 文件和 2 个不同的 .cpp 文件来实现此功能。我尝试使用这个常见问题解答作为guideline 来实现一个小测试用例。代码如下:

test.h

#ifndef TEST_H
#define TEST_H

#include <iostream>
#include <cmath>
#include <complex>

template<typename T> 
class test
public:
static bool IsClose(const T &a, const T &b);
;
#endif

testImpl.h

#include "test.h"

template <typename T> 
bool test<T>::IsClose(const T &a, const T &b)
    return (std::abs(a-b) <= (1e-8 + 1e-5 * std::abs(b)));

testImpl.cpp

#include "testImpl.h"

template class test<int>;
template class test<double>;

ma​​in.cpp

#include "test.h"
#include <iomanip>
int main()
    std::cout << std::boolalpha << test<double>::IsClose(1e-7,1.1e-7) << std::endl;
    return 0;

在使用g++ -o test main.cpp testImpl.cpp 编译时出现以下错误:

main.cpp: In function ‘int main()’:
main.cpp:4:36: error: ‘test’ is not a template
     std::cout << std::boolalpha << test<double>::IsClose(1e-7,1.1e-7) << std::endl;

如果有人能告诉我哪里出错了,我们将不胜感激。提前致谢!!此外,如果有更好的方法来实现我想要做的事情,也欢迎您对此事提出想法。

【问题讨论】:

将所有模板代码放在标题中。只有显式的模板特化实现应该在 cpp 中 @bolov @Elliot 我将test.cpp 的名称更改为testImpl.h,但仍然出现同样的错误。 如果将所有源代码放在一个文件中,它会编译吗?您使用的是哪个 g++ 版本?此外,就像@Elliott 建议的那样,尝试重命名 TEST_H 以不使用前导或尾随下划线。 @Eugene 当我将所有内容放在一个源文件中时它会编译。我正在使用 g++ 7.5.0 版,我尝试删除前导和尾随下划线,但没有效果。我也尝试将此代码作为模板函数而不是模板类,它编译得很好。 @Elliot Ubuntu 18.04 和 CPU 是 i7 第 8 代。 【参考方案1】:

我终于明白了。我需要让编译器知道它需要使用更新版本的 C++。所以, g++ -std=c++17 -o test main.cpp testImpl.cpp 完美地为我编译了代码。

仅当您使用 gcc 版本 7.5.0 时才需要使用 -std 标志。之后的所有版本的 gcc,都可以使用 g++ -o test main.cpp testImpl.cpp

【讨论】:

这有助于解决问题,但没有解释为什么它没有首先编译。这仍然是一个谜(可能是 GCC 7.5.0 中的一个错误,已知或未知)。另外,不客气,但您的回答无需感谢任何人。 *** 应该是很生硬的。 =P @Elliot 看来你是对的,这是 gcc 7.5.0 中的一个错误,我在 gcc 10.1.0 中尝试了相同的代码,但它在没有 -std 标志的情况下工作。

以上是关于仅具有静态方法的模板类使用 .cpp 文件实现给出错误的主要内容,如果未能解决你的问题,请参考以下文章

用模板类特化的方式实现工厂模式

如何在 cpp 文件中为多种类型创建模板类成员实现

模板方法模式具有不同的实现方法参数

在 .cpp 文件中使用类的静态成员

无法强制实例化专用模板

boost::mpi 作为模板类的静态成员