如何在头文件和源文件中组织模板函数和函数
How to organize template-functions and functions, in headers and source files
我正在学习使用模板函数并将代码组织在多个文件中。我看了为什么模板只能在头文件中实现?他们指出我应该在头中实现我的模板函数;我还研究了C++内联函数:声明为这样,定义为这样,还是两者兼而有之?为什么?所以我知道我应该将完全专用的函数定义为头中的内联函数;我研究了在实现头中定义的模板化函数和类时为什么要使用"tpp"文件?他们建议在单独的my.tpp
中定义模板(以及完全专用的模板?),并在我的头的末尾添加#include "my.tpp"
。
现在,作为一个完全初学者,我的问题是:如何将所有这些与常规函数结合起来。
想象一下:
#ifndef IVAL_H
#define IVAL_H
//Function to determine if input string is of a given type
template<typename T>
bool is_type(std::string);
//Specialization when testing integer
//As I also want to accept e.g. 4.0000 as an integer
template<>
bool is_type<int>(std::string);
//Function to get a given type
template<typename T>
T get_type(std::string);
//Finally a normal function to ask for [y/n]
bool yesNo(std::string prompt);
//Include templates definitions
#include"ival.tpp"
#endif /*IVAL_H*/
然后,正如上面引用的问题所建议的那样:
//in ival.tpp
#ifndef IVAL_TPP
#define IVAL_TPP
template<typename T>
bool is_type(std::string input)
{
//How to validate input
}
template<>
bool inline is_type<int>(std::string input)
{
\How to validate when integer
}
template<typename T>
T get_type(std::string prompt)
{
//How to keep asking until valid input
//Using is_type
}
#endif /*IVAL_H*/
最后,作为.cpp
,我的正常函数:
//in ival.cpp
#include "ival.h"
bool yesNo(std::string prompt)
{
//How to ask for [y/n]
//Using get_type<char>
}
这导致了一些关于如何正确组织我的职能的困惑。当在一个头中,我们有模板函数和普通函数时,做我上面做的事情是正常的吗?(正常函数的不同源文件),是被视为模板(即在所有模板所在的文件中内联定义)或函数(即仅在.cpp中定义为所有其他函数)的完全专用函数。
我所做的比在.cpp中定义模板函数更方便,并显式实例化为char, int, double, float
和std::string
您的解决方案对我来说很好。您通常可以在文件ival.h的末尾插入文件ival.tpp的代码,因此只有一个头文件。
如何将所有这些与正则函数结合起来。
通常的规则是:
- 只将正则函数的定义放入*.cpp文件中
- 将所有的模板函数定义、内联函数定义和正则函数声明放在*.h文件中(或者有些人喜欢将其称为*.hpp)。选择一个顺序,使大多数函数只使用上面定义的/call函数
- 仅在必要时(例如循环依赖项):在
*.h
文件的最顶部放置足够的模板和内联函数声明,以便在调用所有被调用的函数之前对其进行声明。这通常只有在特殊情况下才有必要
当在一个头中我们有模板函数和普通函数时,做我上面做的事情是正常的吗?
通常不需要在定义模板函数之前显式声明模板函数,因此这一点经常被省略。这通常只在少数必要的情况下进行,即当模板函数相互引用/调用时。调用图中甚至可能存在循环。只需将其全部声明为内联,并将其实际内联内容留给编译器。
完全专业化的函数是作为模板处理还是作为函数处理?
将它们视为模板。所有能够看到通用模板定义的代码也应该能够看到专门化。否则事情就会变得一团糟(程序的不同部分对同一个调用的函数使用不同的代码)。
在.cpp中定义模板函数并显式实例化为char、int、double、float和std::string时,我所做的是否更方便?
否。除非你有具体的理由,否则不要使用显式模板实例化。不要为了保持头文件的精简而使用显式的模板实例化。
- 使用多个源文件时对类成员函数的未定义引用
- C++,是否有可能/如何定义在.h和.cpp源文件中调用函数的类构造函数
- 如何在源文件中定义模板函数
- "<某些系统标头>:错误:"<在此处插入函数>"在移动源文件后不是"std"的成员
- 获取对源文件中特定函数的所有调用并生成其他文件(使用 C、C++预处理器或脚本)
- 创建 Matlab MEX 函数时,我是否将 mexFunction 放在 c++ 头文件或源文件中
- 函数跨多个C 源文件
- C++编译器在一个源文件中的一个函数调用中引发错误,但在具有相同函数调用的另一个源文件中不会引发错误
- 如何创建用于多个源文件的全局变量/包含/函数
- 将函数放在标题与C 源文件中的位置
- 如何在头文件和源文件中组织模板函数和函数
- 从C源文件调用C++源文件中定义的全局函数
- 如何在源文件中实现嵌套类构造函数
- C++ 将函数放在单独的源文件中
- C++单独编译,不同源文件使用相同函数
- 编译一个源文件,其中包含在标头中声明的函数
- 在C++程序或静态类中具有函数的C源文件
- 别名不同源文件中的函数
- 使用全局变量作为在其他源文件中分配的函数的参数
- 头文件与源文件中的extern函数