1

У меня есть этот кусок кода:C++ без функции согласования для вызова "и«не известно преобразование для аргумента»

class Enum { 
    public: 
     const int &value() const { 
     return value_; 
     } 

     bool operator==(const Enum &other) const { 
     return (other.value() == this->value_); 
     } 

     bool operator!=(const Enum &other) const { 
     return !(*this == other); 
     } 

     bool operator<(const Enum& other) const { 
     return value_ < other.value(); 
    } 

    protected: 
     Enum(const int &value) : value_(value) { 
     } 

     void set_value(int value) { 
     value_ = value; 
     } 

    private: 
     int value_; 
    }; 

    /* 
    * Port-Id Base classes 
    */ 
    class PortIdBase : public Enum { 
    public: 
     virtual ~PortIdBase() {} 
    protected: 
     PortIdBase(int value) : Enum(value) {} 
    }; 

    class PortId : public PortIdBase { 
    public: 
     PortId(int value) : PortIdBase(value) {} 
     PortId() : PortIdBase(0) {} 
     virtual ~PortId() {} 
    }; 

    class GlobalPortId { 
    public: 
     GlobalPortId(const PortIdBase id_base) : base_(id_base) {} 
     virtual ~GlobalPortId() {} 

    private: 
     PortIdBase base_; 
    }; 


    class CfpDevice { 
    public: 
     explicit CfpDevice(int dev_cfp_instance) : instance_(dev_cfp_instance) {} 
     virtual ~CfpDevice() {} 

    private: 
     int instance_; 
    }; 

    class Cfp { 
    public: 
     explicit Cfp(const GlobalPortId &id, 
      CfpDevice* const device) : id_(id), 
            device_(device) {} 
     ~Cfp() { delete device_; } 

    private: 
     const GlobalPortId id_; 
     CfpDevice* const device_; 
    }; 

    int main() { 
     int number_of_devices = 5; 
     for(int i = 0; i < number_of_devices; ++i) { 
     GlobalPortId port(PortId(i)); 
     CfpDevice *cfp_device = new CfpDevice(i); 
     Cfp *cfp = new Cfp(port, cfp_device); 
     } 
     return 0; 
    } 

мне пришлось изменить код, чтобы соответствовать все в одном файле, так что не» t беспокоиться о реализации отдельно от определений и распределения памяти. Я исправлю все в своих оригинальных файлах. Мой вопрос, почему компиляции этого кода у меня есть это сообщение:

test.cc: In function ‘int main()’: test.cc:86:40: error: no matching function for call to ‘Cfp::Cfp(GlobalPortId (&)(PortId), CfpDevice*&)’ Cfp cfp = new Cfp(port, cfp_device); ^ test.cc:86:40: note: candidates are: test.cc:70:12: note: Cfp::Cfp(const GlobalPortId&, CfpDevice) explicit Cfp(const GlobalPortId &id, ^ test.cc:70:12: note: no known conversion for argument 1 from ‘GlobalPortId(PortId)’ to ‘const GlobalPortId&’ test.cc:68:7: note: Cfp::Cfp(const Cfp&) class Cfp { ^ test.cc:68:7: note: candidate expects 1 argument, 2 provided

Однако, если я изменю:

GlobalPortId port(PortId(i)); 

для

GlobalPortId port(static_cast<PortIdBase>(PortId(i))); 

Он работает.

Кроме того, если удалить

GlobalPortId port(PortId(i)); 

и конкретизирует в создании CFP:

Cfp *cfp = new Cfp(GlobalPortId(PortId(i)), cfp_device); 

Он также работает.

Есть ли кто-нибудь, кто мог бы объяснить:

  1. Почему это позволило создать экземпляр CFP, вызывая GlobalPortId и PortId конструкторами в одной и той же линии? Но им не разрешается использовать их, когда вы создаете их отдельно.
  2. Почему не разрешено создавать Cfp, используя «порт» без приведения?

ответ

2

Вы пострадали от самого неприятного разбора. GlobalPortId port(PortId(i)); объявляет функцию, называемую port, которая принимает параметр типа PortId с именем i и возвращает GlobalPortId. Я считаю, что дополнительные круглые скобки будут заботиться о нем: GlobalPortId port((PortId(i)));

+0

Вы правы. Дополнительные параны делают трюк. Я узнал, что C++ 11 позволяет эту конструкцию с фигурными скобками, чтобы избежать этой проблемы синтаксического разбора. Порт GlobalPortId {PortId (i)}; –

0

Вы должны использовать:

GlobalPortId port = GlobalPortId(PortId(i)); 
+1

Попробуйте объяснить свой ответ дальше. –