C++ C++;:不完全类型

C++ C++;:不完全类型,c++,compiler-errors,C++,Compiler Errors,我有以下代码: template<class T> class RandomTreeNode { public: typedef typename RandomTreeFunction<T>::function_ptr function_ptr; RandomTreeNode(): left(NULL), right(NULL), threshold(0.0), is_a_leaf(false), data(NULL), function(0){

我有以下代码:

template<class T>
class RandomTreeNode {

public:
    typedef typename RandomTreeFunction<T>::function_ptr function_ptr;
    RandomTreeNode(): left(NULL), right(NULL), threshold(0.0), is_a_leaf(false), data(NULL), function(0){
    }
    void set_function(function_ptr function){this->function = function;}
    function_ptr get_function(){ return this->function;}

    void set_threshold(double threshold){this->threshold = threshold;}
    double get_threshold(){return threshold;}

    void create_left_child(){this->left = RandomTreeNode<T>();}
    //returning references so that they can be altered in a recursive tree build algo without excessive copying
    RandomTreeNode<T>& get_left_child(){return left;}

    void create_right_child(){this->right = RandomTreeNode<T>();}
    RandomTreeNode<T>& get_right_child(){return this->right;}

    bool is_leaf(){return this->is_a_leaf;}
    void mark_as_leaf(){this->is_a_leaf = true;}

    const std::vector<T> get_data(){
        return data;
    }
    void set_data(std::vector<T>& data){
        this->data = data; 
    }

private:
    RandomTreeNode<T> left;
    RandomTreeNode<T> right;
    double threshold;
    function_ptr function;
    std::vector<T> data;
    bool is_a_leaf;

};
模板
类随机树节点{
公众:
typedef typename RandomTreeFunction::function_ptr function_ptr;
RandomTreeNode():左(NULL)、右(NULL)、阈值(0.0)、为叶(false)、数据(NULL)、函数(0){
}
void set_function(function_ptr function){this->function=function;}
函数_ptr get_function(){返回此->函数;}
void set_threshold(双阈值){this->threshold=threshold;}
双get_threshold(){return threshold;}
void create_left_child(){this->left=RandomTreeNode();}
//返回引用,以便在递归树构建算法中更改引用,而无需过度复制
RandomTreeNode&get_left_child(){return left;}
void create_right_child(){this->right=RandomTreeNode();}
RandomTreeNode&get_right_child(){返回此->right;}
bool is_leaf(){return this->is_ea_leaf;}
void mark_as_leaf(){this->is_a_leaf=true;}
const std::vector get_data(){
返回数据;
}
无效集_数据(标准::向量和数据){
这->数据=数据;
}
私人:
左三叶皂苷;
随机树节点右;
双阈值;
功能\u ptr功能;
std::矢量数据;
布尔是一片叶子;
};

编译时,我得到以下
错误:“RandomTreeNode::left”的类型不完整。知道为什么吗?

因为这是您当前定义的类型。一个类型有一个相同类型的成员是没有意义的(对于初学者来说,它的大小是无限的)。我认为您需要的是指向
随机树节点的指针,而不是直接实例。

因为它是您当前定义的类型。一个类型有一个相同类型的成员是没有意义的(对于初学者来说,它的大小是无限的)。我认为您需要的是指向
RandomTreeNode
的指针,而不是直接实例。

尝试前向声明。在全局范围的程序开始时编写此代码

template<class T>
class RandomTreeNode ;
模板
三烯醇类;

它给您带来错误,因为您正在声明要声明的类型的变量。

请尝试前向声明。在全局范围的程序开始时编写此代码

template<class T>
class RandomTreeNode ;
模板
三烯醇类;

这会给您带来错误,因为您正在声明要声明的类型的变量。

您不能在此类内声明类的实例

在这里你声明
RandomTreeNode左和<代码>随机树节点右侧
在您的
RandomTreeNode
声明中。因此,类型的声明不完整


您应该使用指向
RandomTreeNode
的指针来避免此错误。

您不能在此类内声明类的实例

在这里你声明
RandomTreeNode左和<代码>随机树节点右侧
在您的
RandomTreeNode
声明中。因此,类型的声明不完整


您应该使用指向
随机树节点的指针来避免此错误。

正确编译的代码(http://codepad.org/ltpxM60i)

下面的代码现在已正确编译

**template<class T>
class RandomTreeFunction{
      class function_ptr{
       };
};**
template<class T>
class RandomTreeNode {

public:
    typedef  typename RandomTreeFunction<T>::function_ptr function_ptr;
    RandomTreeNode(): left(NULL), right(NULL), threshold(0.0), is_a_leaf(false), data(NULL), function(0){
    }
    void set_function(function_ptr function){this->function = function;}
    function_ptr get_function(){ return this->function;}

    void set_threshold(double threshold){this->threshold = threshold;}
    double get_threshold(){return threshold;}

    void create_left_child(){this->left = RandomTreeNode<T>();}
    //returning references so that they can be altered in a recursive tree build algo without excessive copying
    RandomTreeNode<T>& get_left_child(){return left;}

    void create_right_child(){this->right = RandomTreeNode<T>();}
    RandomTreeNode<T>& get_right_child(){return this->right;}

    bool is_leaf(){return this->is_a_leaf;}
    void mark_as_leaf(){this->is_a_leaf = true;}

    const std::vector<T> get_data(){
        return data;
    }
    void set_data(std::vector<T>& data){
        this->data = data; 
    }

private:
    RandomTreeNode<T> left;
    RandomTreeNode<T> right;
    double threshold;
    function_ptr function;
    std::vector<T> data;
    bool is_a_leaf;

};
int main(){
return 0;
}
**模板
类随机树函数{
类函数{
};
};**
模板
类随机树节点{
公众:
typedef typename RandomTreeFunction::function_ptr function_ptr;
RandomTreeNode():左(NULL)、右(NULL)、阈值(0.0)、为叶(false)、数据(NULL)、函数(0){
}
void set_function(function_ptr function){this->function=function;}
函数_ptr get_function(){返回此->函数;}
void set_threshold(双阈值){this->threshold=threshold;}
双get_threshold(){return threshold;}
void create_left_child(){this->left=RandomTreeNode();}
//返回引用,以便在递归树构建算法中更改引用,而无需过度复制
RandomTreeNode&get_left_child(){return left;}
void create_right_child(){this->right=RandomTreeNode();}
RandomTreeNode&get_right_child(){返回此->right;}
bool is_leaf(){return this->is_ea_leaf;}
void mark_as_leaf(){this->is_a_leaf=true;}
const std::vector get_data(){
返回数据;
}
无效集_数据(标准::向量和数据){
这->数据=数据;
}
私人:
左三叶皂苷;
随机树节点右;
双阈值;
功能\u ptr功能;
std::矢量数据;
布尔是一片叶子;
};
int main(){
返回0;
}
我认为功能_ptr没有定义

typedef typename RandomTreeFunction<T>::**function_ptr** function_ptr;
typedef typename randomtree函数::**函数**函数**;
对于typename以下是此处应用的规则(参考:-)

规则

typename is prohibited in each of the following scenarios:
        Outside of a template definition. (Be aware: an explicit template specialization (more commonly called a total specialization, to contrast with partial specializations) is not itself a template, because there are no missing template parameters! Thus typename is always prohibited in a total specialization.)
        Before an unqualified type, like int or my_thingy_t.
        When naming a base class. For example, template <class C> class my_class : C::some_base_type { ... }; may not have a typename before C::some_base_type.
        In a constructor initialization list.
    typename is mandatory before a qualified, dependent name which refers to a type (unless that name is naming a base class, or in an initialization list).
    typename is optional in other scenarios. (In other words, it is optional before a qualified but non-dependent name used within a template, except again when naming a base class or in an initialization list.)
typename在以下每种情况下都是禁止的:
在模板定义之外。(请注意:显式模板专门化(与部分专门化相比,通常称为总专门化)本身不是模板,因为没有缺少的模板参数!因此,总专门化中始终禁止使用typename。)
在非限定类型之前,如int或my\u thingy\t。
命名基类时。例如,模板类my_class:C::some_base_type{…};在C::some_base_类型之前可能没有类型名。
在构造函数初始化列表中。
typename在引用类型的限定的从属名称之前是必需的(除非该名称正在命名基类或在初始化列表中)。
typename在其他场景中是可选的。(换句话说,在模板中使用限定但非依赖的名称之前是可选的,但在命名基类或在初始化列表中时除外。)

因此,您可能必须为正确编译的函数\p>代码定义类型(http://codepad.org/ltpxM60i)

下面的代码现在已正确编译

**template<class T>
class RandomTreeFunction{
      class function_ptr{
       };
};**
template<class T>
class RandomTreeNode {

public:
    typedef  typename RandomTreeFunction<T>::function_ptr function_ptr;
    RandomTreeNode(): left(NULL), right(NULL), threshold(0.0), is_a_leaf(false), data(NULL), function(0){
    }
    void set_function(function_ptr function){this->function = function;}
    function_ptr get_function(){ return this->function;}

    void set_threshold(double threshold){this->threshold = threshold;}
    double get_threshold(){return threshold;}

    void create_left_child(){this->left = RandomTreeNode<T>();}
    //returning references so that they can be altered in a recursive tree build algo without excessive copying
    RandomTreeNode<T>& get_left_child(){return left;}

    void create_right_child(){this->right = RandomTreeNode<T>();}
    RandomTreeNode<T>& get_right_child(){return this->right;}

    bool is_leaf(){return this->is_a_leaf;}
    void mark_as_leaf(){this->is_a_leaf = true;}

    const std::vector<T> get_data(){
        return data;
    }
    void set_data(std::vector<T>& data){
        this->data = data; 
    }

private:
    RandomTreeNode<T> left;
    RandomTreeNode<T> right;
    double threshold;
    function_ptr function;
    std::vector<T> data;
    bool is_a_leaf;

};
int main(){
return 0;
}
**模板
氯