[英]The strange behaviour when using c++ specialization template
我是使用c ++模板編程的新手。 我有3個代碼文件
main.cpp中
#include "template_test.h"
#include <iostream>
using namespace std;
int main()
{
mytest<int> mt;
mt.method(1);
system("pause");
return 0;
}
template_test.h
#include <iostream>
using namespace std;
template<class T>
class mytest
{
public:
void method(T input){}
};
template<>
void mytest<int>::method(int input)
{
cout << "ok" << endl;
}
template_test.cpp
#include "template_test.h"
//empty
該代碼在VS2013中生效。 但是,當我將代碼更改為2種情況時,我的代碼都有問題。
1.第一個是帶有鏈接器錯誤代碼的。
main.cpp中
#include "template_test.h"
#include <iostream>
using namespace std;
int main()
{
mytest<int> mt;
mt.method(1);
system("pause");
return 0;
}
template_test.h
#include <iostream>
using namespace std;
template<class T>
class mytest
{
public:
void method(T input);
};
template<class T>
void mytest<T>::method(T input)
{
cout << " " << endl;
}//explicit specialization here
template<>
void mytest<int>::method(int input)
{
cout << "ok" << endl;
}
template_test.cpp
#include "template_test.h"
//empty
2.第二個輸出什么也沒有,而不是正確的答案“確定”。
main.cpp中
#include "template_test.h"
#include <iostream>
using namespace std;
int main()
{
mytest<int> mt;
mt.method(1);
system("pause");
return 0;
}
template_test.h
#include <iostream>
using namespace std;
template<class T>
class mytest
{
public:
void method(T input){}
};
template_test.cpp
#include "template_test.h"
template<>
void mytest<int>::method(int input)
{
cout << "ok" << endl;
}//move from .h to .cpp file here
C ++模板的奇怪行為使我感到困惑。 所以有什么問題?
第一個問題是由您的顯式專業化引起的
template<>
void mytest<int>::method(int input)
{
cout << "ok" << endl;
}
在頭文件中和類定義之外定義, 並且沒有關鍵字inline
。
顯式專業化導致定義實際功能(而不是單純的模板)。 該定義將出現在每個轉換單元中,因此,如果分別編譯template_test.cpp
和main.cpp
,則函數的定義將包含在兩個目標文件中,從而在鏈接時導致多定義錯誤(因為這違反了ODR,一個定義規則)。
最好通過在類模板定義中包括函數定義(通過將整個類模板專用於int
)或使用關鍵字inline
來避免這種情況:
template<>
inline void mytest<int>::method(int input)
{
cout << "ok" << endl;
}
第二個問題是由以下事實引起的:在使用模板專門化之前必須始終對其進行聲明:
(14.7.3 / 6)如果一個模板,一個成員模板或一個類模板的成員是顯式專門化的,則應在首次使用該專門化之前聲明該專門化,這將導致每次翻譯中發生隱式實例化發生這種使用的單位; 無需診斷。 如果程序未提供顯式專門化的定義,並且以某種方式使用專門化會導致隱式實例化,或者該成員是虛擬成員函數,則該程序格式不正確,無需診斷。 對於已聲明但未定義的顯式專門化,永遠不會生成隱式實例化。 [...]
由於您的main.cpp
包含頭文件,但不包含.cpp文件,因此在main.cpp
使用模板專用化的聲明時未知。 您可以通過在標頭文件中包括特殊化(在類模板定義內部(通過對int
整個化整個類模板))或在類模板定義之外使用關鍵字inline
來解決此問題。
您首先提出第二個問題。 使用模板時請記住規則。 請勿將模板實現與cpp文件分開。 將它們全部放在一個.h文件中。
您的第一個代碼在我的VC2012中可以正常編譯,我不確定VC2013有什么問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.