簡體   English   中英

使用C ++專業化模板時的奇怪行為

[英]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.cppmain.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM