Вопрос

I'm trying to design such classes, where one of them is template class, but I'm getting ambiguous error.

template <class v>
class Base
{
protected:
    vector <v> data;

    void sortByStr (string (v::*) () );

};

class Person : Base <Person>
{
    string szSurname;
    string szPhoneNum;

public:
    Person (string surname = "default", string phoneNum = "000 000 000")
        :  szSurname (surname), szPhoneNum (phoneNum)
        {
        };

    virtual void sortBySurname()   {sortByStr (&Person::getSurname);};
    virtual void sortByPhone()     {sortByStr (&Person::getPhone);};
};


class Worker : public Base <Worker>,
               public Person
{
    private:
        string szPosition;
        int nAge;
        bool isBusy;

    public:
        Worker (string surname = "Not Specified",
                string phone = "000-000-000",
                string position = "none",
                short  age = 0,
                bool   busy = 0);
                : Person (surname, phone), szPosition (position), nAge (age), isBusy (busy)
                {};

    void sortByPosition(){sortByStr (&Worker::getPosition);};   // <-sortByStr ambiguous
    void sortByAge()     {sortByNum (&Worker::getAge);};        // <-sortByStr ambiguous
    void sortByStatus()  {sortByBool(&Worker::getBusyStatus);}; // <-sortByStr ambiguous



};

I get:

/Projekt v1.0/people.h||In member function ‘void Worker::sortByPosition()’:|

/Projekt v1.0/people.h|76|error: reference to ‘sortByStr’ is ambiguous|

/Projekt v1.0/base.h|17|note: candidates are: void Base::sortByStr(std::string (v::*)()) [with v = Person; std::string = std::basic_string]|

/Projekt v1.0/base.h|17|note: void Base::sortByStr(std::string (v::*)()) [with v = Worker; std::string = std::basic_string]|

Is it possible to avoid such error in this specific example? I tried to (for checking only) implement class Worker as derived from Base only. It works, but I need access to Person from Worker in my project. I really appreciate help :)

Это было полезно?

Решение

This is because the class Base is inherited twice in class Worker, one directly and one from class Person since it also inherits Base. So there are two copies of Base::sortByStr() method in class worker, one from Person(which it gets from Base), one from Base itself, and thus compiler is confused which one to call. To avoid this, you can use virtual inheritance for class Person.

      class Person: virtual public Base<Person> { ...};
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top