C ++: скрытие некоторых функций - PullRequest
8 голосов
/ 11 декабря 2010

Я переопределил некоторые математические функции (чтобы они были быстрее - то есть: менее точными - или использовали шаблоны).Я помещаю эти функции в пространство имен, и они прекрасно работают.

Однако часто случается так, что я забываю вызывать функции из своего пространства имен (то есть: я забываю писать mymath::cos или using mymath::cos;, когда яхочу позвонить cos), и довольно сложно выяснить, где я это забыл (до сих пор я узнал это только по профилированию).

Учитывая, что

  • I только включают стандартные заголовки math.h или cmath в мой математический заголовок, и что
  • мне нужно включить стандартные математические заголовки (потому что некоторые из моих функций являются просто обертками для стандартного, иЯ хочу, чтобы они были встроенными или они были шаблонными),

есть ли переносимый способ скрыть стандартную математическую функцию, чтобы сообщать об ошибке компиляции, если глобальное пространство имен (то есть: без пространства имен) используются математические функции?

Решением может быть размещение using namespace mymath; в нижней части моего заголовочного файла математики, но это решение не кажется таким уж большим: оно ломает всю цельпространств имен;Я предпочел бы, чтобы в явном виде говорилось, использовать ли функцию из mymath или из std, чтобы я был вынужден выбирать между функцией Fester или более точной без риска забыть об этом.


EDIT :

Во многих ответах говорится, что если я использую cos из глобального пространства имен (без использования std, ни mymath), и включаю cmath (ине math.h), компиляция должна завершиться неудачей.

Я не знаю, что говорит стандарт об этом, но:

#include <cmath>
int main( ) {
    cos( M_PI );
    return 0;
}

прекрасно компилируется с GNU GCC (g++) 4.5.1 (и более старые версии).

Ответы [ 7 ]

4 голосов
/ 11 декабря 2010

Поместите это в заголовочный файл, и включите его везде:

namespace DontUseMe {  
double cos (double) ;  
// ...etc.  
}  
using namespace DontUseMe ;
3 голосов
/ 11 декабря 2010

Если вы включаете только cmath, а не math.h, все функции из этого заголовка должны находиться в пространстве имен std ::.Просто никогда не используйте using namespace std;, и все будет в порядке.(cmath это просто math.h со всеми вещами в пространстве имен)

2 голосов
/ 11 декабря 2010

К сожалению, наиболее надежным решением будет не использовать те же имена функций, что и в стандартной библиотеке.К счастью, стандартные имена функций являются краткими и сильно сокращенными, поэтому такие имена, как cosine(), sine(), exponent(), arctan() будут уникальными (и, возможно, лучше) без необходимости украшать имя неуклюжими префиксами.

В качестве альтернативы вы можете оставить те же имена, но использовать их с большой буквы: Sin(), Cos(), Exp() и т. Д.

2 голосов
/ 11 декабря 2010

Нужно ли включать заголовочные файлы math.h и cmath непосредственно в заголовочный файл? Если вам нужно, попробуйте включить заголовок так:

namespace arbitrary_name
{
  #include <math.h>
}

Он будет содержать все определения math.h в новом пространстве имен, поэтому вы не сможете случайно использовать их где-либо еще.

Это не идеальное решение. Возможно, есть лучший способ сделать это, используя анонимные пространства имен, но решение мне не ясно.

1 голос
/ 11 декабря 2010

Напишите некоторые функции-оболочки в отдельном файле.

#include <math.h>

namespace my_wrapper
{

float sin(float n)
{
    return std::sin(float n);
}

};

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

С современным компилятором, который связывает генерацию временного кода и может встроить в объектфайлы это не должно быть неэффективно ...

1 голос
/ 11 декабря 2010

Как насчет этой идеи: после включения используйте определение следующим образом:

#define sin blahblahblah    (just to generate an error)
#define cos blahblahblah    (just to generate an error)

В результате каждый грех будет заменен бла-бла-блахом, что приведет к ошибке.Но что произойдет, так это то, что mymath :: sin будет заменено на mymath :: blahblahblah (потому что #define работает буквально), поэтому оно также выдаст ошибку.В этом случае, если вы хотите упростить задачу, просто временно определите функцию blahblahblah в mymath, чтобы не показывать ошибку для mymath :: sin, затем скомпилируйте и исправьте все эти ошибки.

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

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

С уважением,
Rafid

0 голосов
/ 11 декабря 2010

Пока мой любимый ответ Клиффорда, но есть и другая альтернатива, которую вы могли бы предусмотреть: изменить стандартные заголовки для этого проекта (только).

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

Это хакерский, но это единственный способ, который я могу придумать, если не проверять код с помощью скрипта для любого вхождения cos / sin, которое не квалифицировано (то есть, непосредственно перед ::).

...