G ++ don't like binding a template method to a var template?

I'm trying to compile with g ++ some code previously developed in Visual C ++ 2008 Express Edition, and it seems that g ++ does not allow me to call the template method for the link returned by the template variable method. I was able to narrow down the problem to the following code:

class Inner
{
public:
  template<typename T>
  T get() const
  {
    return static_cast<T>(value_);
  };
private:
  int value_;
};

class Outer
{
public:
  Inner const& get_inner() { return inner_; };
private:
  Inner inner_;
};

template<typename T>
int do_outer(T& val)
{
  return val.get_inner().get<int>();
}

int main()
{
  Outer outer;
  do_outer(outer);
  return 0;
}

The code compiles under the Microsoft compiler, but g ++ throws an error:

$ g++ -c main.cpp
main.cpp: In function ‘int do_outer(T&)’:
main.cpp:24: error: expected primary-expression before ‘int’
main.cpp:24: error: expected ‘;’ before ‘int
main.cpp:24: error: expected unqualified-id before ‘>’ token

where line 24 refers to return val.get_inner().get<int>();.

If I do the do_outerusual method that gets the link Outer, the code compiles. When creating Inner::get(), the usual method works. And creating a Inner::get()return void and getting a template parameter also works, because below the int specifier becomes unnecessary, that is:

class Inner
{
public:
  template<typename T>
  void get(T& val) const
  {
    val = static_cast<T>(value_);
  };
private:
  int value_;
};

...

template<typename T>
int do_outer(T& val)
{
  int i;
  val.get_inner().get(i);
  return i;
}

...

(g ++ does not apply to the code above.)

. ? gcc/g++? ?

:

$ g++ --version
g++ (Ubuntu 4.3.3-5ubuntu4) 4.3.3
+5
3

?

template<typename T>
int do_outer(T& val)
{
  return val.get_inner().template get<int>();
}

gcc atm, , template . VS.

+8

, , template:

template<typename T>
int do_outer(T& val)
{
  int i;
  val.get_inner().get<int>(i);
  return i;
}

, , val. val.get_inner().get(i) :

1: val .

. , 'val' , - - .

2. val . get_inner (

get_inner - , (. , get_inner - , . , ).

3. val . get_inner () .

, , get_inner , , - .

4. val . get_inner () . get <

, <? , ... , , , ?

, get . , < , . , , , < template-name, < (14.2/3):

(3.4) , , <, < - , .

, val.get_inner(), get. , -, -. '& ;' , , , get int - , .

, ?

template

, get , < .

-

do_outer , : val . get_inner () . get ( , get . ( , . .

+11

, 10 , ++, , , . ( GCC 4.4.1 , BTW).

do_outer

const Inner& inner = val.get_inner();
return inner.get<int>();

GCC Visual ++.

You may consider bug with GCC; either they will fix it, or it will be closed as INVALID, and in this process someone, I hope, will explain why what you are doing is invalid code.

Further update and AHA: Turns out this is not really the right code, GCC just gives a terrible error message. Intel C ++ displays an error message (really useful!):

template.cpp(24): error: type name is not allowed
    return val.get_inner().get<int>();

It made me understand the problem. Change do_inner to

  return val.get_inner().template get<int>();

The code is accepted by both ICC and GCC.

-1
source

All Articles