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


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

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

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

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

in [basic.защита.odr].

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

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

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

2 67

2 ответа:

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

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

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

проще говоря, 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'