Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ template problem in cross-platform code

Tags:

c++

templates

I'm having some trouble getting this code to compile on Linux but it works perfectly in Windows.

Windows compiler: Visual Studio 2005

Linux compiler: gcc version 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);

In Windows this code works perfectly and does exactly what I want it to. In Linux, I get the errors:

error: expected primary-expression before '>' token

error: expected primary-expression before ')' token

for each of the lines with the case statement.

Any ideas?

Thanks, Mike

like image 647
miked Avatar asked Aug 21 '09 22:08

miked


People also ask

Are templates supported in C?

The main type of templates that can be implemented in C are static templates. Static templates are created at compile time and do not perform runtime checks on sizes, because they shift that responsibility to the compiler.

How are CPP templates compiled?

Template compilation requires the C++ compiler to do more than traditional UNIX compilers have done. The C++ compiler must generate object code for template instances on an as-needed basis. It might share template instances among separate compilations using a template repository.

Are C++ templates type safe?

C++ templates are checked at least twice. First, when a template is declared & defined, second when it is instantiated. After a template successfully instantiated it is in a type safe state.


1 Answers

The problem is that when the compiler encounters Op.Execute<char>(); and tries to parse it, it gets confused.

Op is a dependant name, so the compiler doesn't know much about its members. So it doesn't know that Execute is a template function. Instead, it assumes that the < means less than. That you're trying to compare some unknown Execute member to something else.

So instead, the line should look like this:

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

Now the compiler knows that Execute is a template, so when it encounters < it is not "less than", but the beginning of the template parameters.

The problem is similar to how you need typename when specifying types belonging to a dependent name. When you're referring to a template member function, and the template arguments are given explicitly, you need the template keyword.

GCC's behavior is correct, and MSVC is too lenient. If you add the template keyword, your code will work in both compilers (and be correct according to the standard)

like image 61
jalf Avatar answered Oct 17 '22 17:10

jalf