проблема шаблона c ++ в кроссплатформенном коде - PullRequest
5 голосов
/ 22 августа 2009

У меня возникают проблемы с компиляцией этого кода в Linux, но он отлично работает в Windows.

Компилятор Windows: Visual Studio 2005

Компилятор Linux: gcc версия 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)

class DoSomething
{
  public:
    template <class DataType>
    bool Execute()
    {
       //do something here
    }
};


template <class Operator>
TypeSwitch(int DataTypeCode, Operator& Op)
{
   switch (DataTypeCode)
   {
     case 1: return Op.Execute<char>();
     case 2: return Op.Execute<int>();
     //snip;
   }
}  

//To call the operator
TypeSwitch(Code,DoSomething);

В Windows этот код работает отлично и делает именно то, что я хочу. В Linux я получаю ошибки:

ошибка: ожидаемое первичное выражение до маркера '>'

ошибка: ожидаемое первичное выражение до маркера ')'

для каждой строки с оператором case.

Есть идеи?

Спасибо, Mike

Ответы [ 2 ]

13 голосов
/ 22 августа 2009

Проблема в том, что когда компилятор встречает Op.Execute<char>(); и пытается его проанализировать, он запутывается.

Op является зависимым именем, поэтому компилятор мало что знает о его членах. Так что он не знает, что Execute является функцией шаблона. Вместо этого предполагается, что < означает меньше, чем. Вы пытаетесь сравнить какого-то неизвестного члена Execute с чем-то другим.

Таким образом, строка должна выглядеть следующим образом:

case 1: return Op.template Execute<char>();

Теперь компилятор знает, что Execute - это шаблон, поэтому, когда он встречает <, он не «меньше чем», а начало параметров шаблона.

Проблема аналогична необходимости typename при указании типов, принадлежащих зависимому имени. Когда вы ссылаетесь на функцию-член шаблона и аргументы шаблона задаются явно, вам необходимо ключевое слово template.

GCC ведет себя правильно, а MSVC слишком мягок. Если вы добавите ключевое слово template, ваш код будет работать в обоих компиляторах (и будет корректным в соответствии со стандартом)

1 голос
/ 22 августа 2009
 case 1: return Op.template Execute<char>();
 case 2: return Op.template Execute<int>();

См .: template в качестве квалификатора

Кроме того, TypeSwitch () возвращает bool

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...