Почему нет концепции константной правильности для статических функций-членов класса?

Вариант использования:

class A {
  static int s_common;
public:
  static int getCommon () const { s_common; };
};

Обычно это приводит к ошибке:

ошибка: статическая функция-член ‘static int A::getCommon()’ не может иметь cv-qualifier

Это связано с тем, что constness применяется только к объекту, указанному this, который отсутствует в функции-члене static.

Однако, если бы это было разрешено, "константность" функции-члена static могла бы быть легко связана с членами данных static.
Почему эта функция отсутствует в C++; любая логическая причина позади этого?


person iammilind    schedule 11.04.2012    source источник
comment
@keety, этот вопрос связаны, а не дублируются, я видел это и проголосовал за это. Аргумент указателя this, который я также упомянул в своем вопросе, кажется недостаточным.   -  person iammilind    schedule 11.04.2012
comment
круто, но, может быть, лучше, если вы свяжете исходную ветку в вопросе, чтобы получить контекст, или вы возражаете против того, чтобы получить те же ответы   -  person keety    schedule 11.04.2012


Ответы (6)


cv-qualifiers влияют на сигнатуру функции. Итак, вы могли бы:

class A {
  static int s_common;
public:
  static void getCommon () const {  };
  static void getCommon () {  };
};

Теперь... как бы вы назвали const? Нет объекта const для его вызова (ну, вы могли бы вызвать его для объекта const, но это не главное).

Это я только предполагаю, возможно, есть и другие причины. :)

person Luchian Grigore    schedule 11.04.2012
comment
Такое сочетание можно было бы просто считать незаконным. Я не уверен, что это достаточно веская причина, чтобы исключить такую ​​возможность. - person Michael Anderson; 11.04.2012
comment
@MichaelAnderson, почему это незаконно? В стандарте сказано, что вы можете перегрузить с помощью cv-qualifiers. Все может быть признано незаконным, если мы достаточно изменим правила. - person Luchian Grigore; 11.04.2012
comment
-1 @Luchian: новые правила, которые позволили бы static const, должны были бы сделать перегрузку недействительной, поскольку ее нельзя легко разрешить, кроме как путем приведения. вот почему это. поэтому я думаю, что ваш ответ был неправильно выбран в качестве решения: это вовсе не причина, а просто ассоциативное заблуждение. - person Cheers and hth. - Alf; 23.04.2012
comment
@Cheersandhth.-Альф, конечно, вы можете изменить правила, чтобы сделать что-либо недействительным. Но это было всего лишь предположение (как отмечено в самом ответе). Я не думаю, что это неверный ответ только потому, что вы можете придумать, как правила могут измениться, чтобы сделать его недействительным. - person Luchian Grigore; 23.04.2012
comment
Очень хорошее замечание, но, как вы сами подозревали, настоящая причина в другом. Это дано в ответах Никола Боласа и Алока Сейва. - person Frank Puffer; 27.01.2018

Однако, если бы это было разрешено, "константность" статической функции-члена могла бы быть легко связана со статическими элементами данных.

Вот где ваш вопрос становится запутанным. Нестатическая функция-член, объявленная как const, по-прежнему имеет не-const доступ к статическим элементам данных. const применяется только к this (т. е. к нестатическим элементам данных).

Для статической функции-члена не имеет смысла использовать const таким же образом синтаксически, но при этом иметь совершенно другой результат (т. е. доступ к статическим элементам данных const).

Кроме того, статические элементы данных — это не что иное, как глобальные переменные класса, которые имеют элементы управления доступом к классу (общедоступные/частные/и т. д.). Таким образом, для некоторых функций не имеет смысла иметь разный const доступ к ним, особенно в зависимости от их подписи.

person Nicol Bolas    schedule 11.04.2012

Обоснование наличия const cv-qualifier в функциях-членах:
Чтобы указать, что скрытый указатель this, передаваемый в функцию-член, является неизменяемым и не может быть изменен. Функция-член static не имеет скрытого параметра this, поэтому const для функций-членов static не имеет смысла.

Однако, если бы это было разрешено, "константность" статической функции-члена могла бы быть легко связана со статическими членами-данными.

Это не было основанием для использования квалификатора const с самого начала, это очевидно из того факта, что вы не можете применять квалификаторы cv к свободной функции. cv-qualifiers предназначались и предназначены только для this, объекта, функция которого вызывается.

person Alok Save    schedule 11.04.2012
comment
Я также удалил свой комментарий, так как он не имеет смысла без вашего предыдущего комментария. Я чувствую, что начинается бесконечная петля. :)) - person Luchian Grigore; 11.04.2012
comment
Интересно, я просто думал о const как о способе заявить, что функция не изменит объект. Это означает, что это излишне для статической функции (поскольку у нее не имеет объекта), но я не понимаю, почему ее можно запретить, а не просто игнорировать. - person paxdiablo; 02.02.2018

Функция, которая не изменяет какое-либо глобальное состояние, является чистой. C++11 вводит атрибуты, которые могут включать [[pure]] на определенных платформах.

Одна проблема с const заключается в том, что это часть типа функции. Назначение этой функции static const "нормальному" указателю на функцию потребует специального правила преобразования, приведения или затухания. И, как упоминает Лучиан, это допустило бы совершенно неоднозначную перегрузку.

По сути, вы описываете формирование одноэлементного объекта из static членов, совместно использующих общий квалифицированный непрямой путь доступа. Чтобы неконстантный объект казался константным, к нему нужно получить доступ через что-то, но this нет. Изменится ли его decltype? Нет хорошего ответа. Если вы хотите всего этого, поместите их явно внутри объекта class.

person Potatoswatter    schedule 11.04.2012
comment
Неплохо подмечено. Является ли [[pure]] расширением? Обычно я ссылаюсь на ссылку вики для C++11, но не могу найти это с помощью простого grep. - person iammilind; 11.04.2012
comment
@iammilind [[pure]] не является стандартным, и я не думаю, что какая-либо платформа его реализует. Но у GCC есть __attribute__((pure)), а у MSVC есть нечто подобное, IIRC. Атрибуты противоречивы, и среди основных реализаций может быть бойкот (см. недавнюю статью Херба Саттера), поэтому такие вещи, как [[pure]], могут никогда не быть переносимыми. - person Potatoswatter; 11.04.2012

Я предполагаю, что использование static и const в функции-члене для ссылки на константность статических переменных-членов просто никогда не рассматривалось как вариант. ИМО, ваше предложение - довольно странный (но, возможно, разумный) способ смешивания этих двух ключевых слов.

person Michael Anderson    schedule 11.04.2012

Хороший вопрос.

Я считаю, что концептуально константность применяется к четко определенному объекту или структуре данных. Не глобальный/статический и т.д.

Точно так же я могу спросить, почему глобальная (или, альтернативно, специфичная для пространства имен) функция может не быть const, то есть она может обещать не изменять какие-либо глобальные (или специфичные для пространства имен) переменные.

Это не имеет особого смысла ИМХО. Но да, константность статических членов, принадлежащих определенному классу - это может быть полезным в некоторых случаях, ИМХО.

person valdo    schedule 11.04.2012