Вопрос по c++, overload-resolution, overloading, visual-studio-2010 – Если у вас есть как постоянная, так и неконстантная перегрузка, это решается константой объекта, для которого вызывается функция.

9

я есть класс, который выглядит примерно так:

class ClassA
{
  public:
    float Get(int num) const;
  protected:
    float& Get(int num);
}

Вне класса я вызываю функцию Get ().

float foo = classAInstance.Get(i);

Я ожидаю, что это вызовет публичную версию, но вместо этого Visual Studio выдает ошибки:

error C2248: 'ClassA::Get' : cannot access protected member declared in class 'ClassA'

При комментировании защищенной перегрузки и удалении всех ссылок на нее код компилируется.

Почему компилятор пытается использовать недоступный элемент, когда доступен доступный? Есть ли приемлемый способ заставить компилятор выбрать правильную перегрузку? Есть ли где-нибудь ссылка на правила разрешения функций-членов?

Ваш Ответ

2   ответа
5

а проверка доступа - позже.

Если у вас есть как постоянная, так и неконстантная перегрузка, это решается константой объекта, для которого вызывается функция.

7

разрешение перегрузки происходит перед проверкой доступности. Раздел 13.3 стандарта ([over.match]) говорит:

Разрешение перегрузки - это механизм выбора наилучшей функции для вызова, учитывая список выражений, которые должны быть аргументами вызова, и набор функций-кандидатов, которые можно вызывать на основе контекста вызова. Критериями выбора наилучшей функции являются количество аргументов, то, насколько хорошо аргументы соответствуют списку параметров-типов функции-кандидата, насколько хорошо (для нестатических функций-членов) объект соответствует неявному параметру объекта и некоторые другие свойства функции-кандидата. [Примечание: функция, выбранная по разрешению перегрузки, не гарантированно соответствует контексту. Другие ограничения, такие как доступность функции, могут сделать ее использование в контексте вызова некорректным. - конец примечания]

Обычное решение - дать публичным и защищенным функциям разные имена.

Обратите внимание, это иногда полезно, например:

class Blah
{
    const std::string& name_ref;

    Blah(const char*) = delete;

public:
    Blah(const std::string& name) : name_ref(name) {}

    void do_something_with_name_ref() const;
};

std::string s = "Blam";
Blah b(s); // ok

Обратите внимание, чтоname_ref будет читаться только из, так что уместно сделать этоconst, Тем не мение,const ссылки могут связываться с временными и обязательнымиname_ref временная ссылка будет зависать, что приведет к неопределенному поведению вdo_something_with_name_ref().

Blah c("Kablooey!"); // would be undefined behavior
                     // the constructor overload makes this a compile error

Перегрузка частного конструктора предотвращает временнуюstd::st,ring быть неявно построенным и связанным.

Пример кажется опасным. Даноstring func(); и выражениеBlah b(func()) скомпилируется и все равно приведет к зависанию ссылки. Мое правило здесь:Никогда сохранитьconst& параметры. Что ты говоришь? Martin Ba
@MartinBa: Конечно, вы бы тоже хотелиBlah(string&&) = delete; Ben Voigt
Гектометр И тогда возникает вопрос, еслиconst charперегрузка все еще требуется вообще. будетchar* парам привязать кstring const& версия или кstring && версия? :-) Martin Ba

Похожие вопросы