簡體   English   中英

模板元編程:部分專業化的問題

[英]Template Metaprogramming: Problems with Partial Specialization

我正在嘗試探索模板的部分專業化以構建特征系統。 不幸的是,我無法讓全部工作正常進行。 我創建了最簡單的 model 來展示什么不起作用。 我什至不清楚我是否正在嘗試不受支持的東西(實際上我看到了相同性質的例子,但細節是魔鬼)。

我只是在創建一個小示例,其中我有兩個枚舉,並希望根據兩者的組合以不同的方式創建一個字符串。 當然,這只是一個展示問題的虛擬示例,在這種情況下,同樣的事情可以通過許多其他方式完成。

#ifndef TESTTRAITS_H_
#define TESTTRAITS_H_

#include <string>

using namespace std;

enum MovementType {
    WALKS = 0, SWIMS = 1
};

enum AnimalType {
    DOG = 0, CAT = 1, DOLPHIN = 2
};

template<AnimalType A, MovementType B>
struct movementAnimal {
    static const string quality;
};

template<AnimalType A>
struct movementAnimal<A,WALKS> {
    static const string quality;
};

template<AnimalType A>
struct movementAnimal<A,SWIMS> {
    static const string quality;
};

#endif /* TESTTRAITS_H_ */

現在我寫 static 變量的賦值

#include "TestTraits.h"

template<>
const string movementAnimal<DOLPHIN, WALKS>::quality = "Not capable";

template<>
const string movementAnimal<DOLPHIN, SWIMS>::quality = "Excellent";

template<AnimalType A>
const string movementAnimal<A, SWIMS>::quality = "Decent";

template<AnimalType A>
const string movementAnimal<A, WALKS>::quality = "Very Well";

和小主function

#include <iostream>
using namespace std;
#include "TestTraits.h"

int main() {
    cout << movementAnimal<DOLPHIN,WALKS>::quality  << endl;
    cout << movementAnimal<DOG,WALKS>::quality  << endl;
    return 0;
}

如果我編譯我得到錯誤:

/src/TestProject.cpp:15: undefined reference to `movementAnimal<(AnimalType)0, (MovementType)0>::quality[abi:cxx11]' collect2: error: ld returned 1 exit status>

如果我刪除對 motionAnimal<DOG,WALKS>::quality 的引用,那么它可以完美編譯。

我知道它沒有消化部分模板規范

template<AnimalType A>
const string movementAnimal<A, WALKS>::quality = "Very Well";

我不知道為什么以及是否有可能使該模式起作用。

如我所見,您將這些定義放入單獨的文件中。 模板類的定義在TestTraits.h中,但 static 常量的定義在其他地方。 主 CPP 文件僅包含TestTraits.h 這聽起來應該是一個不錯的決定,但在模板的世界里這行不通。

因此,您已經定義了枚舉和模板/部分特化。 您的主 cpp 模塊會看到這些定義。 好的。 編譯器在此處實例化walking dog 時知道模板類:

cout << movementAnimal<DOG,WALKS>::quality  << endl;

編譯器是否看到 static const 的定義? 如果沒有,那么這樣的代碼是無用的:

template<AnimalType A>
const string movementAnimal<A, WALKS>::quality = "Very Well";

當編譯器看到上面的代碼時,它無法知道您將使用的A所有值。 因此,每當您決定DOG WALKS時,此實例化點將看到const string movementAnimal<A, WALKS>::quality的定義;

解決方案是確保來自主 function 的代碼知道模板類的定義和 static 常量的定義。

有兩種解決方案。 首先是將所有內容放入一個 header 文件或包含來自 cpp 文件的兩個文件。 不要忘記包括兩者。

第二種解決方案是在代碼中的某處顯式實例化某些類:

template class movementAnimal<DOG, WALKS>;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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