Вы можете сделать это с версией монго выше 2.2
запрос, подобный этому:
db.coll.find({ 'notes.title': 'Hello MongoDB' }, {'notes. вы можете попробовать с $elemMatch
как Джастин Дженкинс
: 1});
вы можете попробовать с $elemMatch
как Джастин Дженкинс
В самом деле, есть одно правило определения, в котором говорится, что встроенная функция должна быть определена в каждой используемой единице трансляции. Кровавые подробности следуют далее. Первый 3.2 / 3
:
Каждая программа должна содержать ровно одно определение каждой не встроенной функции или объекта, которые используются в этой программе; диагностика не требуется. Определение может явным образом присутствовать в программе, его можно найти в стандартной или пользовательской библиотеке или (при необходимости) оно определено неявно (см. 12.1, 12.4 и 12.8). Встроенная функция должна быть определена в каждой единице перевода, в которой она используется.
И, конечно же, 7.1.2 / 4
:
Встроенная функция должна быть определена в каждой единице перевода, в которой она используется и имеет одно и то же определение во всех случаях (3.2). [Примечание: вызов встроенной функции может встречаться до того, как ее определение появится в блоке перевода. ] Если функция с внешней связью объявлена встроенной в одной единице перевода, она должна быть объявлена встроенной во всех единицах перевода, в которых она появляется; Диагностика не требуется. Встроенная функция с внешней связью должна иметь один и тот же адрес во всех единицах трансляции. Статическая локальная переменная во встроенной функции extern всегда ссылается на один и тот же объект. Строковый литерал во встроенной функции extern - это один и тот же объект в разных единицах перевода.
Однако, если вы определяете свою функцию в определении класса, она неявно объявляется как встроенная
функция. Это позволит вам многократно включать определение класса, содержащее это встроенное тело функции, в вашу программу. Поскольку функция имеет внешнюю
связь, любое ее определение будет относиться к той же функции (или более кровавой - к той же сущности
).
Кровавые подробности о моем требовании. Первый 3.5 / 5
:
Кроме того, функция-член, член статических данных, класс или перечисление области действия класса имеют внешнюю связь, если имя класса имеет внешнюю связь.
Затем ] 3.5 / 4
:
Имя, имеющее область пространства имен, имеет внешнюю связь, если это имя [...] именованного класса (пункт 9), или безымянный класс, определенный в объявлении typedef, в котором класс имеет имя typedef для целей связывания.
Это «имя для целей связывания» - это забавная вещь:
typedef struct { [...] } the_name;
Теперь у вас есть несколько определений одна и та же сущность в ваших программах, другая вещь ODR ограничивает вас. 3.2 / 5
следует за скучным материалом.
Может быть более одного определения типа класса (пункт 9), типа перечисления (7.2), встроенной функции с внешней связью (7.1.2) [ ...] в программе при условии, что каждое определение появляется в разных единицах перевода, и при условии, что определения удовлетворяют следующим требованиям. Если такой объект с именем D определен более чем в одной единице трансляции, то
- каждое определение D должно состоять из одной и той же последовательности токенов; и
- в каждом определении D соответствующие имена, найденные в соответствии с 3.4, должны относиться к объекту, определенному в определении D, или должны относиться к тому же объекту после разрешения перегрузки (13.3) и после сопоставления частичного специализация шаблона (14.8.3) [...]
Сейчас я убрал некоторые неважные вещи. Вышеупомянутые два важных вопроса о встроенных функциях следует помнить. Если вы определяете внешнюю встроенную функцию несколько раз, но определяете ее по-разному, или если вы определяете ее и имена, используемые в ней, разрешаются для разных сущностей, то вы выполняете неопределенное поведение.
Легко запомнить правило, согласно которому функция должна быть определена в каждом TU, в котором она используется. И то, что это то же самое, тоже легко запомнить. Но как насчет этой штуки с разрешением имен? Вот пример. Рассмотрим статическую функцию assert_it
:
static void assert_it() { [...] }
Теперь, поскольку static
предоставит ей внутреннюю связь, когда вы включаете ее в несколько единиц перевода, тогда каждое определение будет определять разные сущность . Это означает, что вам не разрешено использовать assert_it
из внешней встроенной функции, которая будет определена в программе несколько раз: потому что происходит то, что встроенная функция будет ссылаться на одну объект, называемый assert_it
в одном TU, но другой объект с тем же именем в другом TU. Вы обнаружите, что все это скучная теория, и компиляторы, вероятно, не будут жаловаться, но я обнаружил, что этот пример, в частности, показывает связь между ODR и объектами.
Далее следует возвращение к вашей конкретной проблеме.
Следующее - то же самое:
struct A { void f() { } };
struct A { inline void f(); }; void A::f() { } // same TU!
Но это другое, так как функция не является встроенной. Вы нарушите ODR, поскольку у вас есть более одного определения f
, если вы включаете заголовок более одного раза
struct A { void f(); }; void A::f() { } // evil!
Теперь, если вы поместите inline
в объявление f
внутри класса, но затем опустите его определение в заголовке, тогда вы нарушите 3.2 / 3
(и 7.1.2 / 4
, который говорит то же самое, только больше разработка), поскольку функция не определена в этой единице перевода!
Обратите внимание, что в C (C99) inline имеет другую семантику, чем в C ++. Если вы создаете внешнюю встроенную функцию, вам следует сначала прочитать хороший документ (желательно Стандарт), поскольку это действительно сложно в C (в основном, для любого используемого встроенного определения функции потребуется другое, не встроенное определение функции в другом ЕП. статические встроенные функции в C просты в обращении. Они ведут себя так же, как и любая другая функция, за исключением обычной подсказки о «встроенной подстановке». static inline
как в C, так и в C ++ служит только подсказкой для встроенной замены. Поскольку static уже будет создавать другую сущность каждый раз, когда она используется (из-за внутренней связи), inline
просто добавит подсказку inline-замены - не более того.
inline
просто добавит подсказку inline-замены - не более того. s используется (из-за внутренней связи), inline
просто добавит подсказку inline-замены - не более того. Независимо от того, является ли метод на самом деле встроенным, остается на усмотрение компилятора. Однако наличие ключевого слова inline также повлияет на связывание метода.
Связывание в C ++ - не моя специальность, поэтому я открою ссылки для лучшего объяснения.
В качестве альтернативы вы можете просто подождать litb , чтобы предоставить кровавые подробности примерно через час;)
Обратите внимание: когда метод объявлен встроенным, его определение ДОЛЖНО быть вместе с его объявлением.
Что касается ответа harshath.jr, метод не нужно объявлять встроенным, если в его определении есть ключевое слово "inline", и это определение доступно в том же заголовке, т.е. :
class foo
{
void bar();
};
inline void foo::bar()
{
...
}
Это полезно для условного встраивания метода в зависимости от того, является ли сборка « debug » или « release » следующим образом:
// Header - foo.h
class foo
{
void bar(); // Conditionally inlined.
};
#ifndef FOO_DEBUG
# include "foo.inl"
#endif
«Встроенный» файл мог бы выглядеть так:
// Inline Functions/Methods - foo.inl
#ifndef FOO_DEBUG
# define FOO_INLINE inline
#else
# define FOO_INLINE
#endif
FOO_INLINE void foo::bar()
{
...
}
, а реализации могло бы понравиться следующее:
// Implementation file - foo.cpp
#ifdef FOO_DEBUG
# include "foo.inl"
#endif
...
Это не совсем красиво, но у него есть применение, когда агрессивная инлайн-версия становится головной болью отладки.