Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将联合用作树中的项类型,以便存储两种不同的数据类型 请考虑以下代码: union tree_item { tree_item(std::valarray<double> const& point) : point(point) { } tree_item(unsigned coord, double coord_value) : splitting_line({ coord, coord_value }) { } struct { unsigned coord; double coord_value; } splitting_line; std::valarray<double> point; };_C++_C++11_C++14 - Fatal编程技术网

C++ 将联合用作树中的项类型,以便存储两种不同的数据类型 请考虑以下代码: union tree_item { tree_item(std::valarray<double> const& point) : point(point) { } tree_item(unsigned coord, double coord_value) : splitting_line({ coord, coord_value }) { } struct { unsigned coord; double coord_value; } splitting_line; std::valarray<double> point; };

C++ 将联合用作树中的项类型,以便存储两种不同的数据类型 请考虑以下代码: union tree_item { tree_item(std::valarray<double> const& point) : point(point) { } tree_item(unsigned coord, double coord_value) : splitting_line({ coord, coord_value }) { } struct { unsigned coord; double coord_value; } splitting_line; std::valarray<double> point; };,c++,c++11,c++14,C++,C++11,C++14,但我假设,如果我们给coord或coord\u value赋值,这会导致未定义的行为 我想做的就是在中为T使用tree\u项 template<typename T> struct tree_node { tree_node(T const& item) : item(item) { } tree_node(T&& item) : item(std::move(item)) { } bo

但我假设,如果我们给
coord
coord\u value
赋值,这会导致未定义的行为

我想做的就是在中为
T
使用
tree\u项

template<typename T>
struct tree_node
{
    tree_node(T const& item)
        : item(item)
    { }
    tree_node(T&& item)
        : item(std::move(item))
    { }

    bool is_leaf() const noexcept {
        return !left && !right;
    }

    T item;
    std::shared_ptr<tree_node<T>> left, right;
};
模板
结构树节点
{
树节点(T常量和项目)
:项目(项目)
{ }
树节点(T&&item)
:项目(标准::移动(项目))
{ }
bool是_leaf()常量noexcept{
返回!左&!右;
}
T项;
std::共享_ptr左、右;
};
spliting\u line
point
是我要存储在树中的两种类型的项。显然,我可以分别为
分割线
编写基类和派生类。但是,由于在这种情况下,我不想对这些项目执行任何类型的操作(我只想存储这些不同的类型),并且需要使用
dynamic\u cast
或某种类型的标志,这将使我的代码过于复杂


那么,我该怎么办呢?

您应该使用一个类来处理真正的变量类型所需的更多功能,而不是使用
联合:

使用tree\u item=boost::variant<
分裂线,
std::valarray
};

variant
对象将确保根据存储的内容调用正确的析构函数。它还跟踪它所拥有的对象,以便您可以实际对其执行类型安全操作(这在您的
联合上也是不可能的)。

这就是虚拟继承的目的。使用公共基类型,可能称为
tree\u item\u base
,包含两个派生类型,
tree\u item\u point
tree\u item\u spliting\u line
<代码>树节点
将需要使用引用或自动指针类型。

您希望在设计中使用不受限制的联合,为了调用正确的析构函数,您必须存储有关联合内部和外部的信息,例如在树节点内部或某种其他包装类型,这将在某些枚举中保留数据类型,并调用正确的构造函数/析构函数

我已经在gcc/clang上尝试了您的代码,只做了一些轻微的修改,实际上它不会发出任何带有-pedantic的警告

#include <functional>
#include <iostream>  
#include <valarray>

union tree_item
{
    tree_item(std::valarray<double> const& ppoint) : point(ppoint) { 
        //new (&point)std::valarray<double>(ppoint);
    }
    tree_item(unsigned coord, double coord_value)
        : splitting_line({ coord, coord_value })
    { }

    ~tree_item(){
      // cannot call point dtor here because we dont know if it was used
    }

    struct {
        unsigned coord;
        double coord_value;
    } splitting_line;
    std::valarray<double> point;
};

int main() {
    std::valarray<double> point={1,2,3};

    // constructed with std::valarray, destructor must be called manually
    tree_item nn(point);
    std::cout << nn.point[2];
    nn.point.~valarray<double>();

    tree_item nn2(1.0, 2.0);

    return 0;
}
#包括
#包括
#包括
联合树项目
{
树_项(std::valarray const&ppoint):点(ppoint){
//新(&point)标准::valarray(ppoint);
}
树项(无符号坐标、双坐标值)
:拆分_行({coord,coord_值})
{ }
~tree_item(){
//无法在此处调用点dtor,因为我们不知道是否使用了它
}
结构{
未签字合作社;
双坐标值;
}分裂线;
std::阵列点;
};
int main(){
std::valarray point={1,2,3};
//使用std::valarray构造,必须手动调用析构函数
树_项nn(点);

STD::如果没有共同的操作,那么把这两种类型的东西存储在同一数据结构中是否有意义?我觉得人们不会经常问自己这个问题……布瑞恩实际上,他们在同一棵树上是很重要的。我永远不会把联盟用作C++类。不幸的是,我不能在这个过程中使用Boost。project.@0xbadf00d您仍然可以复制他们的操作方式(或找到类似的博客)
using tree_item = boost::variant<
    splitting_line,
    std::valarray<double>
};
#include <functional>
#include <iostream>  
#include <valarray>

union tree_item
{
    tree_item(std::valarray<double> const& ppoint) : point(ppoint) { 
        //new (&point)std::valarray<double>(ppoint);
    }
    tree_item(unsigned coord, double coord_value)
        : splitting_line({ coord, coord_value })
    { }

    ~tree_item(){
      // cannot call point dtor here because we dont know if it was used
    }

    struct {
        unsigned coord;
        double coord_value;
    } splitting_line;
    std::valarray<double> point;
};

int main() {
    std::valarray<double> point={1,2,3};

    // constructed with std::valarray, destructor must be called manually
    tree_item nn(point);
    std::cout << nn.point[2];
    nn.point.~valarray<double>();

    tree_item nn2(1.0, 2.0);

    return 0;
}