Вот однострочный ряд с использованием операций apply
на основе строки apply
[f0]
> dat <- as.data.frame(matrix(rep(seq(4),4),ncol=2))
> colnames(dat) <- c('I','J')
> dat
I J
1 1 1
2 2 2
3 3 3
4 4 4
5 1 1
6 2 2
7 3 3
8 4 4
> mat <- matrix(seq(16),ncol=4)
> mat
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
> dat$K <- apply( dat, 1, function(x,mat) mat[ x[1], x[2] ], mat=mat )
> dat
I J K
1 1 1 1
2 2 2 6
3 3 3 11
4 4 4 16
5 1 1 1
6 2 2 6
7 3 3 11
8 4 4 16
Это вообще не связано с производительностью. Но учтите следующее: вы используете две библиотеки с именами Foo и Bar:
using namespace foo;
using namespace bar;
Все работает нормально, и вы можете без проблем вызвать Blah ()
из Foo и Quux ()
из Bar. . Но однажды вы обновитесь до новой версии Foo 2.0, которая теперь предлагает функцию под названием Quux ()
. Теперь у вас конфликт: и Foo 2.0, и Bar импортируют Quux ()
в ваше глобальное пространство имен. Это потребует некоторых усилий, чтобы исправить это, особенно если параметры функции совпадают.
Если вы использовали foo :: Blah ()
и bar :: Quux ()
], то введение foo :: Quux ()
не было бы событием.
Проблема с помещением с использованием пространства имен
в файлы заголовков ваших классов заключается в том, что это заставляет любого, кто хочет использовать ваши классы (включая файлы заголовков), также 'using' (то есть видеть все внутри) этих других пространств имен.
Однако вы можете свободно помещать оператор using в свои (личные) файлы * .cpp.
Помните, что некоторые люди не согласны с моим высказыванием «чувствуйте бесплатно »- потому что, хотя оператор using
в файле cpp лучше , чем в заголовке (потому что он не влияет на людей, которые включают ваш файл заголовка), они думают это все еще не хорошо (потому что, в зависимости от кода, это может затруднить поддержку реализации класса). В этой записи Супер-FAQ по C ++ говорится:
Директива using существует для устаревшего кода C ++ и для облегчения перехода к пространствам имен, но вам, вероятно, не следует использовать ее на регулярной основе, по крайней мере, в вашем новом коде C ++.
FAQ предлагает две альтернативы :
Объявление-использования:
using std :: cout; // объявление-использования позволяет использовать cout без квалификации
cout << "Значения:";
Просто набираю std ::
std :: cout << "Values:";
Я не думаю, что это обязательно плохая практика при любых условиях, но вы должны быть осторожны при его использовании. Если вы пишете библиотеку, вам, вероятно, следует использовать операторы разрешения области видимости с пространством имен, чтобы ваша библиотека не сталкивалась с другими библиотеками. Что касается кода уровня приложения, я не вижу в этом ничего плохого.
Это зависит от того, где он находится. Если это общий заголовок, то вы уменьшаете значение пространства имен, объединяя его с глобальным пространством имен. Имейте в виду, что это может быть изящным способом создания глобальных модулей.
Не следует использовать директиву using
в глобальной области видимости, особенно в заголовках. Однако бывают ситуации, когда это уместно даже в файле заголовка:
template <typename FloatType> inline
FloatType compute_something(FloatType x)
{
using namespace std; // No problem since scope is limited
return exp(x) * (sin(x) - cos(x * 2) + sin(x * 3) - cos(x * 4));
}
Это лучше, чем явная квалификация ( std :: sin
, std :: cos
...) , потому что он короче и имеет возможность работать с определяемыми пользователем типами с плавающей запятой (через поиск, зависящий от аргументов (ADL)).
Все дело в управлении сложностью. Использование пространства имен будет втягивать в себя вещи, которые вам не нужны, и, таким образом, возможно, затруднит отладку (я говорю, возможно). Использование std :: повсюду труднее для чтения (больше текста и всего такого).
Лошади для курсов - управляйте своей сложностью так, как вы можете и чувствуете себя способным.
Если вы импортируете правые файлы заголовков, у вас внезапно появятся имена вроде шестнадцатеричный
, левый
, плюс
или count
в вашей глобальной области видимости. Это может быть удивительно, если вы не знаете, что std ::
содержит эти имена. Если вы также попытаетесь использовать эти имена локально, это может привести к некоторой путанице.
Если все стандартные вещи находятся в собственном пространстве имен, вам не нужно беспокоиться о конфликтах имен с вашим кодом или другими библиотеками.
Вы должны уметь читать код, написанный людьми, у которых другой стиль и мнение о передовых методах, чем у вас.
Если вы используете только cout
, никто путается. Но когда у вас много летающих пространств имен, и вы видите этот класс, но не совсем уверены, что он делает, наличие явного пространства имен действует как своего рода комментарий. С первого взгляда вы можете увидеть «о, это операция файловой системы» или «она выполняет сетевые действия».
Рассмотрим
// myHeader.h
#include <sstream>
using namespace std;
// someoneElses.cpp/h
#include "myHeader.h"
class stringstream { // Uh oh
};
Обратите внимание, что это простой пример. Если у вас есть файлы с 20 включениями и другими объектами импорта, вам нужно будет пройти через множество зависимостей, чтобы решить проблему. Хуже всего то, что вы можете получить несвязанные ошибки в других модулях в зависимости от конфликтующих определений.
Это не ужасно, но вы избавите себя от головной боли, не используя его в файлах заголовков или в глобальном пространстве имен. Возможно, это нормально делать это в очень ограниченных пределах, но у меня никогда не было проблем с вводом дополнительных пяти символов, чтобы уточнить, откуда берутся мои функции.
Другая причина - неожиданность.
Если я увижу cout << blah
, вместо std :: cout << blah
, я думаю: Что это за cout
? Это нормальный cout
? Это что-то особенное?
Я тоже считаю это плохой практикой. Почему? Однажды я подумал, что функция пространства имен состоит в разделении вещей, поэтому мне не следует портить его, помещая все в один глобальный мешок.
Однако, если я часто использую cout и cin, я пишу : с использованием std :: cout; с использованием std :: cin;
в файле .cpp (никогда в файле заголовка, поскольку он распространяется с помощью #include
). Думаю, никто в здравом уме никогда не назовет поток cout
или cin
. ;)
I agree with everything Greg wrote, but I'd like to add: It can even get worse than Greg said!
Library Foo 2.0 could introduce a function, Quux()
, that is an unambiguously better match for some of your calls to Quux()
than the bar::Quux()
your code called for years. Then your code still compiles, but it silently calls the wrong function and does god-knows-what. That's about as bad as things can get.
Keep in mind that the std
namespace has tons of identifiers, many of which are very common ones (think list
, sort
, string
, iterator
, etc.) which are very likely to appear in other code, too.
If you consider this unlikely: There was a question asked here on Stack Overflow where pretty much exactly this happened (wrong function called due to omitted std::
prefix) about half a year after I gave this answer. Here is another, more recent example of such a question.
Так что это настоящая проблема.
Вот еще один факт: много-много лет назад меня раздражало то, что все элементы стандартной библиотеки были добавлены к std ::
. Затем я работал в проекте, где с самого начала было решено, что как директивы using, так и объявления
запрещены, за исключением областей видимости функций. Угадай, что? Большинству из нас потребовалось всего несколько недель, чтобы привыкнуть к написанию префикса, и еще через несколько недель большинство из нас даже согласились, что это действительно сделало код более читабельным . Для этого есть причина: Нравится ли вам более короткая или более длинная проза - это субъективно, но префиксы объективно добавляют ясности коду. Не только компилятор, но и вам также легче увидеть, какой идентификатор является упомянуто.
Через десятилетие, этот проект вырос до нескольких миллионов строк кода. Поскольку эти обсуждения возникают снова и снова, мне однажды было любопытно, как часто (разрешенная) функция-область видимости using
на самом деле использовалась в проекте. Я поискал его в источниках и нашел только один или два десятка мест, где он использовался. Для меня это указывает на то, что после попытки разработчики не находят std ::
достаточно болезненным, чтобы использовать директивы using даже один раз на каждые 100 kLoC, даже там, где это разрешено.
Итог: Явно префикс всего не вредит, требует очень небольшого привыкания и имеет объективные преимущества. В частности, это упрощает интерпретацию кода компилятором и читателями - и это, вероятно, должно быть основной целью при написании кода.
Поскольку эти обсуждения возникают снова и снова, мне однажды было любопытно, как часто (разрешенная) функция-область видимости using
на самом деле использовалась в проекте. Я поискал его в источниках и нашел только один или два десятка мест, где он использовался. Для меня это указывает на то, что после попытки разработчики не находят std ::
достаточно болезненным, чтобы использовать директивы using даже один раз на каждые 100 kLoC, даже там, где это разрешено.
Итог: Явно префикс всего не вредит, требует очень небольшого привыкания и имеет объективные преимущества. В частности, это упрощает интерпретацию кода компилятором и читателями - и это, вероятно, должно быть основной целью при написании кода.
Поскольку эти обсуждения возникают снова и снова, мне однажды было любопытно, как часто (разрешенная) функция-область видимости using
фактически использовалась в проекте. Я поискал его в источниках и нашел только один или два десятка мест, где он использовался. На мой взгляд, это означает, что после попытки разработчики не находят std ::
достаточно болезненным, чтобы использовать директивы using даже один раз в 100 kLoC, даже если это разрешено.
Итог: Явно префикс всего не вредит, требует очень небольшого привыкания и имеет объективные преимущества. В частности, это упрощает интерпретацию кода компилятором и читателями - и это, вероятно, должно быть основной целью при написании кода.
Однажды мне было любопытно, как часто (разрешенная) область видимости функции с использованием
фактически использовалась в проекте. Я поискал его в источниках и нашел только один или два десятка мест, где он использовался. Для меня это указывает на то, что после попытки разработчики не находят std ::
достаточно болезненным, чтобы использовать директивы using даже один раз на каждые 100 kLoC, даже там, где это разрешено.
Итог: Явно префикс всего не вредит, требует очень небольшого привыкания и имеет объективные преимущества. В частности, это упрощает интерпретацию кода компилятором и читателями - и это, вероятно, должно быть основной целью при написании кода.
Однажды мне было любопытно, как часто (разрешенная) область видимости функции с использованием
фактически использовалась в проекте. Я поискал его в источниках и нашел только один или два десятка мест, где он использовался. Для меня это указывает на то, что после попытки разработчики не находят std ::
достаточно болезненным, чтобы использовать директивы using даже один раз на каждые 100 kLoC, даже там, где это разрешено.
Итог: Явно префикс всего не вредит, требует очень небольшого привыкания и имеет объективные преимущества. В частности, это упрощает интерпретацию кода компилятором и читателями - и это, вероятно, должно быть основной целью при написании кода.
t find std ::
достаточно болезненно, чтобы использовать директивы using даже один раз на каждые 100 kLoC, даже если это было разрешено использовать.
Итог: явное добавление префиксов ко всему не причиняет никакого вреда, требует очень мало привыкание, и имеет объективные преимущества. В частности, это упрощает интерпретацию кода компилятором и читателями - и это, вероятно, должно быть основной целью при написании кода.
t find std ::
достаточно болезненно, чтобы использовать директивы using даже один раз на каждые 100 kLoC, даже если это было разрешено использовать.
Итог: явный префикс для всего не приносит никакого вреда, требует очень мало привыкание, и имеет объективные преимущества. В частности, это упрощает интерпретацию кода компилятором и читателями - и это, вероятно, должно быть основной целью при написании кода.