Компилятор будет генерировать код для каждого экземпляра шаблона при использовании шаблона во время этапа компиляции. В процессе компиляции и компоновки файлы .cpp преобразуются в чистый объектный или машинный код, который в них содержит ссылки или неопределенные символы, поскольку файлы .h, которые включены в ваш main.cpp, не имеют реализации YET. Они готовы быть связаны с другим объектным файлом, который определяет реализацию для вашего шаблона, и, следовательно, у вас есть полный исполняемый файл a.out. Однако, поскольку шаблоны необходимо обрабатывать на этапе компиляции, чтобы сгенерировать код для каждого экземпляра шаблона, который вы делаете в своей основной программе, ссылка не поможет, поскольку компиляция main.cpp в main.o, а затем компиляция вашего шаблона .cpp в template.o, а затем ссылка не будет достигать цели шаблонов, потому что я связываю различные экземпляры шаблонов с одной и той же реализацией шаблона! И шаблоны должны делать обратное, т. Е. Иметь одну реализацию, но допускать много доступных экземпляров посредством использования одного класса.
Значение typename T
get заменяется во время этапа компиляции, а не на этапе связывания, поэтому, если я попытаюсь для компиляции шаблона без замены T
в качестве конкретного типа значения, чтобы он не работал, потому что это определение шаблонов - это процесс времени компиляции, а мета-программирование btw - все об использовании этого определения.
Вам нужен контракт, чтобы различать пункты меню предложений и остальные пункты меню, затем при добавлении предложений сначала удалите существующие пункты предложений, а затем добавьте новые.
Здесь в качестве примера я использую свойство Tag
для ToolStripMenuItem
в качестве контракта, и все пункты полосы меню, имеющие в своем теге suggestion
, рассматриваются как рекомендации:
public void Suggest(List<string> words, ContextMenuStrip menu)
{
string suggestion = "suggestion";
menu.Items.Cast<ToolStripItem>().Where(x => x.Tag == (object)suggestion)
.ToList().ForEach(x => menu.Items.Remove(x));
words.ToList().ForEach(x =>
{
var item = new ToolStripMenuItem(x);
item.Tag = suggestion;
item.Click += (s, e) => MessageBox.Show(x);
menu.Items.Insert(0, item);
});
}
И как использование, для одного слова:
Suggest(new List<string> { "something", "something else" }, contextMenuStrip1);
Для другого слова:
Suggest(new List<string> { "another", "another one" }, contextMenuStrip1);