Вложенные функции не позволяются, но почему прототипы вложенной функции позволяются? [C++]

Это, вероятно, будет исправлено в более новых версиях MongoDB ( https://jira.mongodb.org/browse/SERVER-14204 ), а пока просто исправьте формулу.

brew edit mongodb

Найдите блок, который выглядит следующим образом:

args = %W[
  --prefix=#{prefix}
  -j#{ENV.make_jobs}
  --cc=#{ENV.cc}
  --cxx=#{ENV.cxx}
  --osx-version-min=#{MacOS.version}
]

И измените минимальную версию OS X на 10,9, например:

args = %W[
  --prefix=#{prefix}
  -j#{ENV.make_jobs}
  --cc=#{ENV.cc}
  --cxx=#{ENV.cxx}
  --osx-version-min=10.9
]

РЕДАКТИРОВАТЬ: Дополнительный шаг для DP3, DP4, PB1

Все еще в файле, добавьте следующие 3 строки чуть выше def install.

  def patches
    { :p1 => 'https://gist.githubusercontent.com/LinusU/a1771562fec0201c54cd/raw/98825f9fbe93b8cc524e05a9c0e99864e8301731/mongodb.diff' }
  end

А затем выполнить обновление:

brew upgrade mongodb

7
задан Community 23 May 2017 в 12:08
поделиться

6 ответов

Ваш прототип - это просто « Перенаправленное объявление ». Пожалуйста, ознакомьтесь со статьей в Википедии.

По сути, она говорит компилятору «не тревожьтесь, если метка SomeFun используется таким образом». Но ваш компоновщик - это то, что отвечает за поиск правильного тела функции.

На самом деле вы можете объявить фиктивный прототип, например, 'char SomeFun ()', и использовать его во всем своем main. Вы получите сообщение об ошибке только тогда, когда ваш компоновщик попытается найти тело вашей фиктивной функции. Но ваш компилятор с этим справится.

Есть много преимуществ. Вы должны помнить, что тело функции не всегда находится в одном и том же файле исходного кода. Он может находиться в связанной библиотеке. Кроме того, эта связанная библиотека может иметь особую «подпись ссылки».

8
ответ дан 6 December 2019 в 05:56
поделиться

Кстати, в C ++ 03 есть обходной способ определения локальных функций. Это требует злоупотребления функцией локального класса:

int main()
{
    struct Local
    {
        static string Some()
        {
            return "";
        }
    };
    std::cout << Local::Some() << std::endl;
}
7
ответ дан 6 December 2019 в 05:56
поделиться

Это соглашение C - как и многие другие - принятое C ++.

Возможность объявлять функцию внутри другой функции в C - это решение, которое большинство программистов, вероятно, сочтет прискорбным. и ненужное. В частности, с современным дизайном ООП, где определения функций сравнительно меньше, чем в C.

Если вы хотите иметь функции, которые существуют только в рамках другой функции, два варианта: boost :: lambda и C ++ 1x лямбда .

5
ответ дан 6 December 2019 в 05:56
поделиться

Относительно того, почему ваше объявление

void f() {
    void g(); g();
}

лучше, чем это

void g();
void f() {
    g();
}

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

void f() {
    int g; 
    // oops, ::g is shadowed. But we can work around that
    {
        void g(); g();
    }
}

Конечно, в C ++ мы могли вызвать функцию g , используя its_namespace :: g () - но в старые времена C, это было бы невозможно, и эта вещь позволяла программисту по-прежнему получать доступ к функции. Также обратите внимание, что хотя синтаксически это не то же самое, семантически следующее также объявляет функцию в локальной области, которая на самом деле нацелена на другую область.

int main() {
    using std::exit;
    exit();
}

В качестве примечания: есть больше ситуаций, подобных этой, когда целевая область действия объявления - , а не область, в которой появляется это объявление. Как правило, объект, который вы объявляете, становится членом области в котором появляется объявление. Но это не всегда так. Рассмотрим, например, объявления друзей, где это происходит

struct X { friend void f() { std::cout << "WoW"; } };
int main() { void f(); f(); } // works!

Несмотря на то, что объявление функции (и определение!) f произошло в пределах X , сущность (сама функция ) стал членом охватывающего пространства имен.

есть и другие ситуации, подобные этой, где целевая область действия объявления - , а не область, в которой появляется это объявление. Как правило, объявляемая вами сущность становится членом области, в которой появляется объявление. Но это не всегда так. Рассмотрим, например, объявления друзей, где это происходит

struct X { friend void f() { std::cout << "WoW"; } };
int main() { void f(); f(); } // works!

Несмотря на то, что объявление функции (и определение!) f произошло в пределах X , сущность (сама функция ) стал членом охватывающего пространства имен.

есть и другие ситуации, подобные этой, где целевая область действия объявления - , а не область, в которой появляется это объявление. Как правило, объявляемая вами сущность становится членом области, в которой появляется объявление. Но это не всегда так. Рассмотрим, например, объявления друзей, где это происходит

struct X { friend void f() { std::cout << "WoW"; } };
int main() { void f(); f(); } // works!

Несмотря на то, что объявление функции (и определение!) f произошло в пределах X , сущность (сама функция ) стал членом охватывающего пространства имен.

Рассмотрим, например, объявления друзей, где это происходит

struct X { friend void f() { std::cout << "WoW"; } };
int main() { void f(); f(); } // works!

Несмотря на то, что объявление функции (и определение!) f произошло в пределах X , сущность (сама функция ) стал членом охватывающего пространства имен.

Рассмотрим, например, объявления друзей, где это происходит

struct X { friend void f() { std::cout << "WoW"; } };
int main() { void f(); f(); } // works!

Несмотря на то, что объявление функции (и определение!) f произошло в пределах X , сущность (сама функция ) стал членом охватывающего пространства имен.

5
ответ дан 6 December 2019 в 05:56
поделиться

Прототипы функций - это подсказки для компилятора. Они указывают, что функции реализованы где-то еще, если еще не обнаружены . Ничего лишнего.

3
ответ дан 6 December 2019 в 05:56
поделиться

Когда вы объявляете прототип, вы в основном говорите компилятору подождать, пока компоновщик его разрешит. В зависимости от того, где вы пишете прототип, применяются правила определения объема. Нет ничего технически неправильного в написании прототипа внутри вашей функции main () (хотя IMHO немного запутаннее), это просто означает, что функция известна только локально внутри main (). Если бы вы объявили прототип в верхней части исходного файла (или чаще в файле заголовка), прототип / функция были бы известны во всем исходном коде.

string foo()
{
  string ret = someString();  // Error
  return ret; 
}

int main(int argc,char**argv)
{
   string someString();
   string s = somestring(); // OK
   ...
}
3
ответ дан 6 December 2019 в 05:56
поделиться
Другие вопросы по тегам:

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