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

Это только что вышло в контексте Другой вопрос.

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

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

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

в [basic.def.odr].

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

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

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

69

Решение

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

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

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

57

Другие решения

Проще говоря, 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's 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's definition must be present

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

12

По вопросам рекламы [email protected]