0
Base{
public:
    Base(int i);
    virtual void doSomething(int z);
}
Derived:public Base{
public:
    Derived(int j);   
}
void myFunc(list<Base> myList,int y){
        for(list<Base>::iterator it = myList.begin();it!=myList.end();++it){
            it->doSomething(y);
        }
    }
main(){

    list<Derived> dList;
    myFunc(dList)
}

I can't seem to pass a list of Derived instead of base. I understand that it can be problematic to do this since than one could add different derived types to the list but I only want to change the objects on the list, not add any more objects. I tried playing around with const but that still did not help.I can't use the for_each function since do something gets an argument. Any ideas?

user3872358
  • 105
  • 2
  • 10
  • why not pass a `list` that is filled with `Derived` objects ? – Sander De Dycker Feb 03 '15 at 10:08
  • 2
    This is *obviously* not your real code. – T.C. Feb 03 '15 at 10:08
  • If `Derived` instances can be passed instead of `Base` ones, `list` and `list` are two completely different types though. – JBL Feb 03 '15 at 10:10
  • The simpler way would be to use template. – Jarod42 Feb 03 '15 at 10:12
  • @JBL I have 2 types of derived and i want to use a function defined in base on a list of both types of derived – user3872358 Feb 03 '15 at 10:17
  • `std::list` and `std::list` are two different types entirely. Just because their value types are derivations means nothing (and you're eventually setting yourself up for a helluva [slicing problem](http://stackoverflow.com/questions/274626/what-is-object-slicing) if you continue down this road). Nor is there any polymorphism in this. To do that right you need pointers or references to your objects; you have neither. – WhozCraig Feb 03 '15 at 10:17
  • @WhozCraig I also tried using pointers (i.e list) but visual studio tells me that it can't convert between list to list – user3872358 Feb 03 '15 at 10:24
  • @user3872358 that's because the original storage of your `Derived*` pointer list should have been `Base*` in the first place. And in doing so smart pointers are generally whats for dinner. [See example](http://ideone.com/wma2BR) – WhozCraig Feb 03 '15 at 11:12

1 Answers1

1

I have 2 types of derived and i want to be to use a function defined in base on a list of both types of derived

Then use a template:

template<typename T>
void myFunc(list<T> myList, int y) {
    for(typename list<T>::iterator it = myList.begin(); it!=myList.end(); ++it){
        it->doSomething(y);
        //use any function present in Base
    }
}

This function will accept any list of any instance of type Base or any of its derived classes.

You can't force the compiler to use polymorphism to accept a list<T> where it expects a list<U>, whatever T and U are, because these will always be unrelated polymorphically-wise.

JBL
  • 12,588
  • 4
  • 53
  • 84
  • is there any way of forcing the compiler to to accept list if it accepts list assuming T is derived from U? – user3872358 Feb 03 '15 at 10:32
  • @user3872358 No. Not without templates. **These are different, polymorphically unrelated types** – JBL Feb 03 '15 at 10:37
  • And you'd need a `typename` there too. Or just `auto`. – T.C. Feb 03 '15 at 10:37
  • 1
    To be clear, this will accept any `std::list<>` of **any type** that exposes a member called `doSomething` that takes an `int` argument. Neither `Base` nor `Derived` have anything to do with it, save for they fulfill that requirement. So too would `SomeClass` if it had a member `Type doSomething(int)`. – WhozCraig Feb 03 '15 at 10:41
  • 1
    There are ways to force `T` to derive from `U` with SFINAE or `static_assert`. – Jarod42 Feb 03 '15 at 10:56
  • 1
    Yep, C++11's [std::is_base_of](http://en.cppreference.com/w/cpp/types/is_base_of) could be used for that. – JBL Feb 03 '15 at 10:58