在使用模板编写C ++时遇到3个问题。似乎VS2013可以编译下面的代码。
代码在这里:
// template_test.h
#include <iostream>
using namespace std;
template<class T>
class mytest
{
public:
void method(T input);
void common();
};
template <>
class mytest<char>
{
public:
void method(char input);
void common();
};
template<class T>
void mytest<T>::method(T input)
{
cout << input << endl;
}
template<class T>
void mytest<T>::common()
{
cout << "common" << endl;
}
// template_test.cpp
#include "template_test.h"
void mytest<char>::method(char input)
{
cout << "char:" << input << endl;
}
void mytest<char>::common()
{
cout << "common" << endl;
}
// main.cpp中
#include "template_test.h"
using namespace std;
int main()
{
mytest<char> test_char;
test_char.method('1');
test_char.common();
mytest<int> test_int;
test_int.method(1);
test_int.common();
system("pause");
return 0;
}
1.在mytest :: method
的实现中template<class T>
void mytest<T>::method(T input)
{
cout << input << endl;
}
我可以删除第二个T表达式吗?我在VS2013中尝试使用以下代码而不是原始cpp,并且无法编译。
template<class T>
void mytest::method(T input)
{
cout << input << endl;
}
看起来很奇怪,我需要以如此多的模板参数的复杂形式使用它。
2.在.h文件中,我宣布了课程&#39; mytest&#39;使用模板专业化
template <>
class mytest<char>
{
public:
void method(char input);
void common();
};
并且每个函数的实现都在
中// template_test.cpp
#include "template_test.h"
void mytest<char>::method(char input)
{
cout << "char:" << input << endl;
}
void mytest<char>::common()
{
cout << "common" << endl;
}
我的问题是,当我将.hpp文件中的实现与非专业化模板类的实现一起放在.h文件中时,VS2013也会报告错误代码。
我知道非专业化模板类的声明和实现应该在同一个头文件中,因为c ++不应该允许在其他文件中展示非专业化模板类。但为什么专门化模板类的声明和实现应该在不同的代码文件中呢?
3.在头文件中
template<class T>
class mytest
{
public:
void method(T input);
void common();
};
template <>
class mytest<char>
{
public:
void method(char input);
void common();
};
很明显,这个功能常见于&#39;是专业化和非专业化模板类的常见部分。但是,专业化将专注于全班。我只想保留常用功能,因此不需要在专业化版本中编写相同的功能。我不知道该怎么做。
我是使用c ++模板编程领域的新手,上面的3个问题基本且简单。我在谷歌搜索一些问题,但仍然不知道。所以我在这里发布我的问题。
答案 0 :(得分:2)
<T>
可以省略template <typename T> void mytest<T>::method(T input)
吗?
没有。虽然在简单的情况下似乎是多余的,但在更复杂的情况下,例如,当存在多个部分特化时,它变得必要。保持语法一致也很有帮助。
当将完全专用的类模板的成员函数的定义放入标题时,会出现“错误”(我假设你得到多个声明的符号)。
完全专用的类模板的成员函数被视为非类模板的成员函数:只有一个版本,编译器永远不需要隐式实例化它。因此,函数不隐式内联,就像任何函数模板的情况一样,并且可能需要由编译器实例化。如果要将定义放入标题中,则需要将其明确声明为inline
。
如何在类模板及其专业化之间共享函数?
除了语法之外,类模板及其任何特化都没有任何共同之处。他们是完全独立的阶级。有两种方法可以在不同的专业化之间共享通用功能:
根据您的常用功能需要做什么,一种或另一种方法效果更好。
答案 1 :(得分:1)
DietmarKühl对1的回答的一小部分补充:感受差异:
实现非专业化类模板template <class T> class mytest
:
template <class T>
void mytest<T>::method(T input)
{
// ...
// use of input
}
为对象指针实现部分类模板特化template <class T> class mytest<T*>
的方法:
template <class T>
void mytest<T*>::method(T* input)
{
// ...
// use of *input
}
为指向另一个类数据成员的指针实现部分类模板特化template <class U, class V> class mytest<U V::*>
的方法:
template <class U, class V>
void mytest<U V::*>::method(V& object, U V::* input)
{
// ...
// use of object.*input
}
实现完整类模板专业化template <> class mytest<char>
的方法:
void mytest<char>::method(char input)
{
// ...
// use of input
}
实现非专业化类模板template <class T> class mytest<T>
的完全专业化方法:
template <>
void mytest<int>::method(int input)
{
// ...
// use of input
}