c++ - 为什么自定义数据的 thrust::sort 需要默认构造函数而 STL::sort 不需要?

标签 c++ sorting stl cuda thrust

我正在尝试使用推力按最小 x 坐标对一组三角形进行排序:

struct real3 
{
    float x, y, z;
};

struct triangle
{
    real3 p1, p2, p3;

    float Xmin, Xmax;

    triangle(real3 ip1, real3 ip2, real3 ip3) :p1(ip1), p2(ip2), p3(ip3)
    {
        Xmax = (p1.x > p2.x) ? ((p1.x > p3.x) ? p1.x : p3.x) : ((p2.x > p3.x) ? p2.x : p3.x);
        Xmin = (p1.x < p2.x) ? ((p1.x < p3.x) ? p1.x : p3.x) : ((p2.x < p3.x) ? p2.x : p3.x);
    }
};

bool triangle_less_Xmin(const triangle& f, const triangle& b)
{
    return f.Xmin < b.Xmin;
}

thrust::device_vector<triangle> devXXX(XXX);
thrust::sort(devXXX.begin(), devXXX.end(), triangle_less_Xmin);

但在编译时,一条错误消息提示“类 tringle 不存在默认构造函数”。但是如果我使用 std::vector 进行如下排序:

std::vector<triangle> sss;
std::sort(sss.begin(), sss.end(), triangle_less_Xmin);

一切顺利。此外,如果我将 triangle(){} 添加到结构中,thrust 也可以很好地编译。 那么,问题是什么?据我所知,排序不需要创建新数据。我应该在默认构造函数中做一些特殊的事情吗?


30 分钟后编辑

我在推力源代码中找到了这个,虽然不太清楚确切的含义。这是错误指向的地方:

__host__ inline static result_type host_path(execution_policy<DerivedPolicy> &exec, Pointer ptr)
{
  // when called from host code, implement with assign_value
  // note that this requires a type with default constructor
  result_type result;

  thrust::host_system_tag host_tag;
  cross_system<thrust::host_system_tag, DerivedPolicy> systems(host_tag, exec);
  assign_value(systems, &result, ptr);

  return result;
}

最佳答案

您的问题中已经包含错误来源和解决方案,并且编译器提供了非常有用的错误消息。

但是为了完整起见,Thrust 要求您的 triangle 类具有默认构造函数,尽管我不确定您发布的代码是否准确指出了代码库(或您的代码库)中的确切位置devXXX 实际上是一个主机 vector 而不是设备 vector ),某处的推力是在没有参数的情况下实例化你的类,导致你看到的失败。

一般来说,在定义带有显式非默认构造函数的类时,您还应该提供自己的默认构造函数,因为提供任何构造函数定义会禁用编译器的隐式默认构造函数。

所以这没问题:

struct triangle
{
    real3 p1, p2, p3;

    float Xmin, Xmax;

};

triangle t;  // Implicit default constructor called

这样就可以了

struct triangle
{
    real3 p1, p2, p3;

    float Xmin, Xmax;

    triangle() {};
    triangle(real3 ip1, real3 ip2, real3 ip3) :p1(ip1), p2(ip2), p3(ip3)
    {
        Xmax = (p1.x > p2.x) ? ((p1.x > p3.x) ? p1.x : p3.x) : ((p2.x > p3.x) ? p2.x : p3.x);
        Xmin = (p1.x < p2.x) ? ((p1.x < p3.x) ? p1.x : p3.x) : ((p2.x < p3.x) ? p2.x : p3.x);
    }
};

triangle  t; // Explicit default constructor called 

但是你的定义

struct triangle
{
    real3 p1, p2, p3;

    float Xmin, Xmax;

    triangle(real3 ip1, real3 ip2, real3 ip3) :p1(ip1), p2(ip2), p3(ip3)
    {
        Xmax = (p1.x > p2.x) ? ((p1.x > p3.x) ? p1.x : p3.x) : ((p2.x > p3.x) ? p2.x : p3.x);
        Xmin = (p1.x < p2.x) ? ((p1.x < p3.x) ? p1.x : p3.x) : ((p2.x < p3.x) ? p2.x : p3.x);
    }
};

triangle t; // Syntax error here, no default constructor

不行,因为您在没有提供自己的情况下覆盖了编译器的默认构造函数。您应该将您的类与 std::sort 一起工作这一事实视为意外,而不是 Thrust 中的任何缺陷。

关于c++ - 为什么自定义数据的 thrust::sort 需要默认构造函数而 STL::sort 不需要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33913206/

相关文章:

c++ - 在模板构建器模式中排除重复的构造函数调用

c - 冒泡排序 - 交换计数器方法

python - Python中连接两个坐标的多米诺骨牌路径

c++ - std::map 键类必须满足哪些要求才能成为有效键?

c++ - 如何将 wstring 转换为字符串?

c++ - 是否允许将 unordered_map 转换到 map 上?

c++ - std::pair 赋值运算符的性能问题是什么?

c++ - 为什么 Vector 中的 Erase 和 Insert 函数会使迭代器失效?

c++ - 1Gbit 以太网快速扰码器

java - 如何在 Android 应用程序中运行静态内部类