Can different thrust iterator be returned by a virtual function

One thing that really bothers me is that when I use Thrust iterators, I want to return an iterator for different derived classes, however there is no common parent iterator class for thrust::constant_iterator, thrust::counting_iterator, or thrust::transform_iterator.

below is what i want to achieve, is there anyway to make it work?

class Base
{
virtual some_iterator GetIterator() =0;
}

class Derived1 : public Base
{
  virtual some_iterator GetIterator() { 
  return thrust::constant_iterator<int>(0);
  };
}

class Derived2 : public Base
{
  virtual some_iterator GetIterator() { 
  return thrust::counting_iterator<int>(0);
  };
}

class Derived3 : public Base
{
  thrust::device_vector<int> a;
  virtual some_iterator GetIterator() { 
  return a.begin();
  };
}

You could use templates instead of inheritance.

class Derived1
{
  auto GetIterator() { 
  return thrust::constant_iterator<int>(0);
  };
}

class Derived2
{
  auto GetIterator() { 
  return thrust::counting_iterator<int>(0);
  };
}

class Derived3{
{
  thrust::device_vector<int> a;
  auto GetIterator() { 
  return a.begin();
  };
}

template<class Derived>
void useIterator(Derived& derived){
    auto iter = derived.GetIterator();
    //use it
}

int main(){
   Derived3 d3;
useIterator(d3);
  Derived1 d1;
   useIterator(d1);
}

Thank you for your kind reply. However, I must use the inheritance approach due to the architecture of my entire project.

Can you return a std::variant<thrust::constant_iterator<int>, thrust::counting_iterator<int>, thrust::transform_iterator<int>)? Or return your own class hiding that variant inside?

I can, but I hope it can return something that can be directly used as an iterator.

Then create your own type, which is an iterator and internally contains the variant.

any reference?

Which specific iterator type do you want? You wrote, you want to directly use it as iterator.

Here you can see an example how to define your own iterator:

I do not think iterator_adaptor works, since it is a template and the type depends on the type of the Iterator to be adapted. I want a iterator (not a template, but a class) which can adapt all kinds of iterators as long as thrust::iterator_traits::value_type is double. will it be possible?

You want a single iterator type, so you can choose one, which covers all your cases. You still can internally in your class rely on other iterators.

For example:
If sometimes your inner iterator is const, you can only provide a const view to your data.

You need the least common denominator.

Except if you copy the data.

Could you show me how to do it? for example I want a single iterator type to adapt both constant_iterator<double> and couting_iterator<double>? I can not come up with a way to do it.

I am not so experienced with iterators, but I try to tell how it can be done:

Solution 1

Inside your iterator class you have one double variable, where you always copy the next value to.
When a dereference() is requested, you return the address or a reference to that double variable.
You internally decide, which value to copy to it. You can keep other iterators internally in your class, which you can call in turn

Solution 2

During dereference() you just call the internal iterator and forward the result. So you do not need to keep your own double variable.

The thrust iterators are modelled similarly to the boost iterators. So you could possibly find material, tutorials and documention for boost, which helps for thrust.

I got your point, basically I need to write a new thrust iterator, and inside it, the adapted iterator should be chosed. I think maybe this is the only way to do it although it is not elegant. Thanks.