cl :: vector vs std :: vector:不同的迭代器行为

时间:2012-01-31 15:15:53

标签: c++ vector iterator opencl

编辑:根据PlasmaHH的建议添加了具有内存位置的调试输出。

我不明白cl :: vector<>的不同行为在OpenCL的C ++绑定中。请考虑以下代码:

标题Top.hpp

class Top {
public:
    void setBool(bool b);
    bool getBool();
private:
    bool status;
};

来源Top.cpp

#include "Top.hpp"   

void Top::setBool(bool b) {
    std::cout << (void*)this << " setBool("<< b<< ")\n";
    status = b;
}

bool Top::getBool() {
    std::cout << (void*)this << " getBool() returns " << status << std::endl;
    return status;
}

使用上述内容:

#define __NO_STD_VECTOR

#include <iostream>
#include "CL/cl.hpp"
#include "Top.hpp"

using namespace cl;
using namespace std;

cl::vector<Top> js;

int main() {
    js.push_back(Top());
    js[0].setBool(true);
    cout << js[0].getBool() << endl;
    for(cl::vector<Top>::iterator i = js.begin(); i != js.end(); ++i) {
        (*i).setBool(false);
    }
    cout << js[0].getBool() << endl;
}

使用__NO_STD_VECTOR覆盖std :: vector。输出是

0x6021c0 setBool(1)
0x6021c0 getBool() returns 1
0x7fffae671d60 setBool(0)
0x6021c0 getBool() returns 1

因此迭代器返回的位置肯定是错误的。

将上述内容与std::vector一起使用(当然,将名称空间更改为std)会得到预期的输出:

0x1be0010 setBool(1)
0x1be0010 getBool() returns 1
0x1be0010 setBool(0)
0x1be0010 getBool() returns 0

这个迭代器的行为不同,但它应该替换std :: vector以避免兼容性问题。我错过了什么吗?

2 个答案:

答案 0 :(得分:4)

在任何想象中都不是OpenCL的专家,但我很感兴趣所以我去了CUDA/OpenCL Computing。我看来他们的*运算符返回副本而不是引用:

00706         T operator *()
00707         {
00708             return vec_[index_];
00709         }

而(first,non-const)vector []运算符返回引用:

00621     T& operator[](int index)
00622     {
00623         return data_[index];
00624     }
00625   
00626     T operator[](int index) const
00627     {
00628         return data_[index];
00629     }

尝试直接迭代向量(使用旧的“int i = 0,...”)并查看是否给出了不同的结果。如果是这样,您可能需要输入错误报告(先检查),因为这是*运算符的意外行为。

答案 1 :(得分:1)

从地址判断我怀疑这是一个64位构建,并且cl向量的迭代器operator*是按值而不是通过引用返回,不允许访问原始元素。作为实验,您可以尝试使用->运算符代替i->setBool(false);来查看是否实现了这一点。