簡體   English   中英

如何正確聲明自引用模板類型?

[英]How to properly declare a self-referencing template type?

如何聲明引用自身的模板類型?

template <class T = Animal> class Animal
{
public:
    T getChild ();
}

有了這個,我得到一個關於缺少類型說明符的編譯器錯誤。 我試圖向前聲明Animal ,但沒有成功。

我正在嘗試施加類型約束。 一只Lion只能在小時候有一只Lion ,一只Bear有一只Bear ,依此類推。

編輯

我將發布實際 class 的一部分。 它是可以出現在鏈表中的類的模板:

template <class T = Linked<T> > class Linked
{
private:
    T* m_prev;
    T* m_next;
}

我想強制 class 只能指向同一 class (或子類)的 object 。

在這種情況下,您需要在類型名稱定義中為 Animal 指定一些類型參數,否則它將是類型構造中的“無限遞歸”:

template<class T> class Animal;//you'll need this forward declaration

template <class T = Animal<int> > class Animal //int is just an example
{
public:
    T getPrey ();
}

OP 已得到回答,但我想插話,因為問題的直接原因不是遞歸,正如其他人聲稱的那樣。 這不起作用的最簡單原因是 class 模板不是類型。 它們是模板。 同樣,function 模板也不是函數。 所以這一切都是荒謬的:

template<typename T> int function_template(int);
typedef int function_type(int);
void eats_a_function(function_type&); // needs a reference to function

std::vector< std::vector > vec0; // std::vector is not a type
std::vector< std::list > vec1; // std::list is not a type
eats_a_function(function_template); // function_template is not a function

請注意,在vec1的情況下, std::liststd::vector無關。 模板在實例化時已完全定義(假設包含 header)。 它仍然行不通。

相反,以下工作:

std::vector< std::vector<int> > vec2; // std::vector<int> is a type
std::vector< std::list<double> > vec3; // std::list<double> is a type
eats_a_function(function_template<long>); // function_template<long> is a function

請注意,在 vec2 的情況下,可以傳遞模板本身的實例化。


作為記錄,使用眾所周知的間接層編寫引用自身的模板的玩具問題的玩具解決方案:

// expects a template that expects a type
template<template<class> class T> struct indirection {};

// forward decl. for defaulting the parameter
template<typename T> struct recursive;

// template that expects a type
template<typename T = indirection<recursive> > struct recursive {};

考慮到模板可以做的事情很少( indirection內的T參數),它並不是非常強大。 當然可以編寫一個rebind風格的元函數來返回T的實例化。

您不能創建模板類型為 class 本身的模板 class。 這是您的編譯器無法緩解的邏輯遞歸。 由於模板要求編譯器在遇到特定類型(例如 Animal )時構造 object,因此您必須對模板類型進行完整定義。 否則,編譯器將遞歸地嘗試構造對象。 由於您的 object 自引用,這將是一個非終止遞歸。

這個用例似乎比模板更適合 inheritance。

這樣做會讓你編譯:template class Animal { public: T getPrey (); }

或者,如果您真的不想使用默認參數:

template <class T=Cheetah> class Animal
{
public:
    T getPrey ();
}

然而,cheetah 不得將其自身或 Animal 作為其潛在的模板類型之一。

執行鏈表之類的常用方法是:

template <class T> class Linked
{
private:
    Linked<T>* m_prev;
    Linked<T>* m_next;
}

這對你有用嗎?如果沒有,你想通過這種方式實現什么?

暫無
暫無

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

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