использование только определенных функций из библиотеки?

#c #libraries #sqrt #cmath

#c #библиотеки #sqrt #cmath

Вопрос:

я хотел бы использовать только определенные функции из math.h (БЕЗ включения всей библиотеки)

например, мне нужно использовать «sqrt» и «exp», но у меня есть переменные с именем «y1» (и, возможно, другие), которые конфликтуют с определениями в math.h

как я могу использовать только определенные функции из такой библиотеки?

я пытался

 #define sqrt cmath::sqrt
  

но это не сработало, я видел нечто подобное раньше с

 #define cout std::cout
  

я думаю, поэтому я подумал, что это может сработать.

есть идеи?

Комментарии:

1. да, это так. я многопоточен.

2. Какой math.h вы имеете в виду? C-Runtime math.h? Или стандартная библиотека C <math> (у которой нет .h)? Или что-то совсем другое?

3. <cmath> который, я полагаю, использует math.h

4. Переменная like y1 не должна конфликтовать ни с чем, объявленным в любом стандартном заголовке. Какую именно ошибку вы получаете?

5. driver.cpp:18: ошибка: ‘float y1’ повторно объявлен как символ другого типа /usr/include/architecture/i386/math.h: 524: ошибка: предыдущее объявление ‘double y1 (double)’

Ответ №1:

Поместите свой код в свое собственное пространство имен. Используя оператор пространства имен (::), вы можете различать переменные с одинаковыми именами (и которые находятся в одной области видимости).

Комментарии:

1. означает ли это, что мне придется создавать свою собственную функцию sqrt?

2. Нет. Вы просто будете использовать myNamespace::y1 для своей переменной. Но подумайте еще раз. Если бы у меня было столкновение имен со стандартной библиотекой, я бы всегда просто выбирал другое имя для своей переменной.

Ответ №2:

Просто использовать их?

 #include <cmath>

int main()
{
    double d = 4.0;
    sqrt(d);
    exp(d);
}
  

Вы также можете явно указать пространство имен:

 #include <cmath>

int main()
{
    double d = 4.0;
    std::sqrt(d);
    std::exp(d);
}
  

Вы можете, если хотите, вводить определенные имена из пространств имен, не вводя все пространство имен. Это делается с помощью using ключевого слова. Пожалуйста, не создавайте #define для этого:

 #include <string>

using std::string;

int main()
{
    string s = "foo";
}
  

Комментарии:

1. это не работает — я не могу #include <cmath>, потому что он конфликтует с различными переменными, которые я использую. дело в том, что я хочу использовать функцию в <cmath>, не включая всю библиотеку.

2. @Laurbert515 — #include заставляет препроцессор выгружать содержимое включаемого файла, выборочного включения нет.

Ответ №3:

Да, вы можете просто использовать нужные части.

Просто создайте свой собственный частичный mini_cmath.заголовок h для тех функций / глобалов, к которым вам нужен доступ (при условии, что они не конфликтуют!).

Как отмечали некоторые, невозможно использовать только #include для данного фрагмента (если только в включенном заголовке нет макросов препроцессора для включения такой функции, например, windows.h)

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


Однако, в более общем плане — глобальные переменные — плохая идея в целом, но если вы абсолютно должны использовать их по, надеюсь, веским причинам, тогда вы должны поместить их в пространство имен и ссылаться на них в своем источнике по полному имени:

 namespace AcmeCorp {
  int g_fubar;
}
AcmeCorp::g_fubar = 9;
  

Комментарии:

1. итак, я бы просто скопировал / вставил функции, определенные в math.h, в свой собственный заголовок и связал это?

2. Пока мы говорим о функциях в стиле C-runtime, абсолютно. Если мы говорим о шаблонах STL, это сложнее (если не невозможно) реализовать, потому что они, как правило, сложны, определены в самих заголовках и переплетены. Однако даже в этом случае это возможно, если вы скопируете нужную вам часть (которая не требует ничего по ссылке, если она полностью шаблонная).

Ответ №4:

Просто #include <cmath> . Если ваши имена переменных вызывают такую проблему, переименуйте их. Вы не можете включить только часть файла.

Комментарии:

1. просто кажется сумасшедшим, что что-то такое простое, как «y1», конфликтует с предопределенной функцией. неужели нет способа включить ТОЛЬКО sqrt из файла заголовка?

2. Я не понимаю, почему это кажется таким странным? Это просто объявление, которое уже использовалось, точно так же, как если бы вы объявили переменную с именем q1 и попытались определить ее в другом месте.

3. проблема в том, что y1 определяется как функция в другом месте, и я хочу использовать ее как значение с плавающей точкой.

4. Итак, либо измените имя переменной, либо инкапсулируйте ее в класс или пространство имен, если это возможно. Не имеет значения, как это было определено cmath — вы не можете использовать его для своих собственных имен.

Ответ №5:

Редактировать: Почему a должен y1 конфликтовать с чем-либо в math.h? Используйте свое собственное пространство имен. Вы все равно сможете использовать sqrt и получать доступ к материалам из своего пространства имен, разрешая через mynamespace::y1 .

В любом случае, cmath это псевдоним файла заголовка math.h . std это пространство имен, в котором содержится cout объект iostream.h .

Таким образом, хотя вы можете использовать std::cout , вы не можете выполнить такое же разрешение области с заголовочным файлом. Вам просто нужно включить math.h или cmath .

И вам не нужно использовать #define for cout подобным образом. Просто добавьте a using namespace std , и вам не придется разрешать область.

И использование всего пространства имен не вызывает никаких накладных расходов, если это то, что вас беспокоит. Приветствия!

Комментарии:

1. В зависимости от платформы вы увидите в заголовке такие вещи math.h : extern double y1 ( double ); pubs.opengroup.org/onlinepubs/000095399/functions/y1.html

2. y1 определен в cmath … driver.cpp:18: ошибка: ‘float y1’ повторно объявлен как символ другого типа /usr/include/architecture/i386/math.h: 524: ошибка: предыдущее объявление ‘double y1 (double)’

3. @birryree Ах! Тогда, я полагаю, это не является частью стандартного C . : P

Ответ №6:

y1() является одним из нескольких расширений POSIX для математической библиотеки C. Вы можете удалить эти расширения, не определяя следующие макросы перед включением <cmath> :

 #undef _SVID_SOURCE
#undef _BSD_SOURCE
#undef _XOPEN_SOURCE
  

Также очень хорошая идея в целом избегать размещения каких-либо собственных имен в глобальном пространстве имен, поскольку существует большая вероятность столкновения, если вы используете какие-либо библиотеки C. Избегайте глобальных переменных, когда можете, и, если вы должны использовать один, поместите его в свое собственное пространство имен.