Компилятору позволяют проигнорировать встроенный в случае шаблонной специализации?

Я использую эти инструменты:

ClipX для буфера обмена.

UltraMon для нескольких мониторов.

RegexBuilder для для создания регулярных выражений в.NET.

Перестановка Панели задач для перестановки окон.

5
задан BostonLogan 19 November 2009 в 01:10
поделиться

5 ответов

Вы неправильно понимаете значение часто упоминаемой возможности «игнорировать встроенный».

Ни одному компилятору не разрешается игнорировать спецификатор inline , используемый в объявлении функции, и последствия, которые этот спецификатор имеет по отношению к правилу единого определения (ODR).

Когда кто-то говорит, что компилятору разрешено "ignore inline" означает только то, что компиляторы не обязаны фактически встраивать вызовы к рассматриваемой функции. «Игнорировать встроенную функцию» означает генерировать обычный (не встроенный) вызов функции для встроенной функции.

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

В вашем исходном примере вы не должны получать ошибок компоновщика.

5
ответ дан 18 December 2019 в 14:47
поделиться

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

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

7
ответ дан 18 December 2019 в 14:47
поделиться

Это определено стандартом, и, судя по всему, компилятор полностью соответствует в этом отношении. Связь - это все, что вам нужно. Неявные экземпляры шаблонов имеют «особую» связь, как и встроенные функции. Также существует static (ключевое слово), которое устарело в пользу анонимных пространств имен:

namespace {
    …declarations…
}

Итак, да, эта специализация (в вашем примере) имеет ту же связь, что и:

void some_other_function(int& val) {
    // some int specific implementation
}

Фактически, компилятор может бормотать о встраивании специализация, в вашем примере, говоря, что они не совпадают. Так что лучше всего пометить их как встроенными (или иначе).

1
ответ дан 18 December 2019 в 14:47
поделиться

Я считаю, что вы можете явно объявить метод как extern, а затем поместить специализацию в .cpp. Я пробовал нечто подобное в прошлой жизни с GCC, но я не помню точных деталей того, как это работало. В журнале MSDN есть статья об этом , которая может помочь.

0
ответ дан 18 December 2019 в 14:47
поделиться

На самом деле вы видите, что правило One Definition Rule (ODR) имеет особый случай для встроенных функций, в котором каждый TU может иметь определение. Если функция, такая как ваша явная специализация int, не является встроенной, вы получите несколько ошибок определения во время ссылки. Такие встроенные функции все еще имеют внешнюю связь. Шаблоны функций - это шаблоны , поэтому они подчиняются другим правилам. Экземпляры / специализации шаблона функции - это функции .

Использование встроенных функций, как и для любой функции, является лишь подсказкой, но вы можете применить ее, если функция короткая (как и для любой функции) или если вы просто хотите оставить его в шапке. Вот пример без встроенного:

Заголовочный файл:

template<class TYPE>
void some_function(TYPE& val) {
  // some generic implementation
}

template<>
void some_function<int>(int& val);

Файл реализации (.cpp):

template<>
void some_function<int>(int& val) {
  // some int specific implementation
}
0
ответ дан 18 December 2019 в 14:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: