Подтвердить что ты не робот

Функция участника со статической связью

Я пытаюсь понять, почему следующее сообщение об ошибке:

class Foobar {
 public:
  static void do_something();
};

static void Foobar::do_something() {} // Error!

int main() {
  Foobar::do_something();
}

Эти ошибки с "error: невозможно объявить функцию-член" static void Foobar:: do_something() "иметь статическую связь" в g++, а "ошибка:" статический "может быть указан только внутри определения класса" в clang++.

Я понимаю, что способ исправить это - удалить "статический" в определении do_something в строке 6. Однако я не понимаю, почему это проблема. Это обыденная причина, например, "диктует грамматика С++" или что-то более сложное происходит?

4b9b3361

Ответ 1

Я думаю, что проблема здесь в том, что ключевое слово static имеет несколько разных значений в С++, а код, который вы написали выше, использует их двумя разными способами.

В контексте функций-членов static означает, что "эта функция-член не имеет объекта-приемника. Это в основном нормальная функция, вложенная внутри области действия класса".

В контексте объявлений функций static означает "эта функция ограничена только этим файлом и не может быть вызвана из других мест".

Когда вы внедрили функцию, написав

static void Foobar::do_something() {} // Error!

компилятор интерпретировал static здесь, чтобы означать "Я реализую эту функцию-член, и я хочу сделать эту функцию локальной только для этого файла". Это не допускается в С++, потому что это вызывает некоторую путаницу: если несколько разных файлов все определили собственную реализацию функции-члена, а затем объявили их static, чтобы избежать коллизий при связывании, вызов одной и той же функции-члена из разных мест приведет к поведению

К счастью, как вы отметили, есть простое исправление: просто удалите ключевое слово static из определения:

void Foobar::do_something() {} // Should be good to go!

Это прекрасно, потому что компилятор уже знает, что do_something является функцией-членом static, так как вы рассказали об этом ранее.

Надеюсь, это поможет!