Подтвердить что ты не робот

Что значит "использовать ODR-что-то"?

Это только что появилось в контексте другого вопроса.

По-видимому, функции-члены в шаблонах классов создаются только в том случае, если они используются ODR. Может кто-нибудь объяснить, что именно это означает. В статье в Википедии об одном правиле определения (ODR) не упоминается "ODR-использование".

Однако стандарт определяет его как

Переменная, имя которой отображается как потенциально оцениваемое выражение, используется odr, если это не объект, который удовлетворяет требованиям для отображения в постоянном выражении (5.19), и немедленно применяется преобразование lvalue-to-rval (4.1).

в [basic.def.odr].

Edit: По-видимому, это неправильная часть, и весь абзац содержит несколько определений для разных вещей. Это может быть актуальным для функции члена шаблона шаблона:

Неперегруженная функция, имя которой отображается как потенциально оцениваемое выражение или член набора функций-кандидатов, если оно выбрано с помощью разрешения перегрузки при упоминании потенциально оцениваемого выражения, используется odr, если только оно не является чистым виртуальным функция и ее имя явно не квалифицированы.

Однако я не понимаю, как это правило работает в нескольких единицах компиляции? Все ли функции-члены создаются, если я явно создаю шаблон шаблона?

4b9b3361

Ответ 1

Это просто произвольное определение, используемое стандартом для укажите, когда вы должны предоставить определение для объекта (как против просто объявления). Стандарт не говорит просто "используется", поскольку это можно интерпретировать в разных контекст. И какое-то использование ODR действительно не соответствует тому, что обычно ассоциируется с "использованием"; например, виртуальный функция всегда используется ODR, если она не является чистой, даже если она не является фактически называемый где угодно в программе.

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

Что касается шаблонов, используемая ODR - это только часть вопроса; другая часть - это экземпляр. В частности, §14.7 охватывает при создании экземпляра шаблона. Но эти два связаны между собой: while текст в §14.7.1 (неявный экземпляр) довольно длинный, Основной принцип заключается в том, что шаблон будет создан только если он используется, и в этом контексте используется ODR-использование. Таким образом, функция-член шаблона класса будет только создаваться если он вызывается, или если он виртуальный, а сам класс инстанцирован. Сам стандарт рассчитывает на это во многих места: std::list<>::sort использует < для индивидуального элементов, но вы можете создать экземпляр списка по типу элемента который не поддерживает <, если вы не вызываете sort on он.

Ответ 2

В простом слове, odr-used означает, что что-то (переменная или функция) используется в контексте, где должно быть определено его определение.

например,

struct F {
   static const int g_x = 2;
};

int g_x_plus_1 = F::g_x + 1; // in this context, only the value of g_x is needed.
                             // so it OK without the definition of g_x

vector<int>  vi;
vi.push_back( F::g_x );      // Error, this is odr-used, push_back(const int & t) expect
                             // a const lvalue, so it definition must be present

Обратите внимание, что вышеперечисленный push_back, переданный в MSVC 2013, не соответствует стандарту, как gcc 4.8.2, так и clang 3.8.0, сообщение об ошибке: undefined ссылка на `K:: g_x '