Что значит "использовать ODR-что-то"?
Это только что появилось в контексте другого вопроса.
По-видимому, функции-члены в шаблонах классов создаются только в том случае, если они используются ODR. Может кто-нибудь объяснить, что именно это означает. В статье в Википедии об одном правиле определения (ODR) не упоминается "ODR-использование".
Однако стандарт определяет его как
Переменная, имя которой отображается как потенциально оцениваемое выражение, используется odr, если это не объект, который удовлетворяет требованиям для отображения в постоянном выражении (5.19), и немедленно применяется преобразование lvalue-to-rval (4.1).
в [basic.def.odr].
Edit: По-видимому, это неправильная часть, и весь абзац содержит несколько определений для разных вещей. Это может быть актуальным для функции члена шаблона шаблона:
Неперегруженная функция, имя которой отображается как потенциально оцениваемое выражение или член набора функций-кандидатов, если оно выбрано с помощью разрешения перегрузки при упоминании потенциально оцениваемого выражения, используется odr, если только оно не является чистым виртуальным функция и ее имя явно не квалифицированы.
Однако я не понимаю, как это правило работает в нескольких единицах компиляции? Все ли функции-члены создаются, если я явно создаю шаблон шаблона?
Ответы
Ответ 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 '