#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.html2. 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. Избегайте глобальных переменных, когда можете, и, если вы должны использовать один, поместите его в свое собственное пространство имен.