c++ - default template class argument confuses g++? -


yesterday ran g++ (3.4.6) compiler problem code have been compiling without problem using intel (9.0) compiler. here's code snippet shows happened:

template<typename a, typename b> class foo { };  struct bar {    void method ( foo<int,int> const& stuff = foo<int,int>() ); }; 

the g++ compiler error is:

foo.cpp:5: error: expected `,' or `...' before '>' token foo.cpp:5: error: wrong number of template arguments (1, should 2) foo.cpp:2: error: provided `template<class a, class b> struct foo' foo.cpp:5: error: default argument missing parameter 2 of `void bar::method(const foo<int, int>&, int)' 

apparently, default argument not accepted when written way, , compiler assumes instead of second template argument new function argument specified, expects default value because stuff argument has one. can compiler creating typedef, , compiles fine:

template<typename a, typename b> class foo { };  struct bar {    typedef foo<int,int> footype;    void method ( footype const& stuff = footype() ); }; 

so can solve problem, don't understand going on. miss c++ (template?) language feature here , doing wrong, or g++ compiler wrong in not accepting first piece of code?

note btw compiles ...

template<typename a, typename b> class foo { };  void method ( foo<int,int> const& stuff = foo<int,int>() ); 

i not sure bug in g++ (since version 4.2.4). code passes in g++ 4.4 (see update below). in order have code compile other versions of compilers can add set of parenthesis around default argument:

template<typename a, typename b> class foo { };  struct bar {   void method ( foo<int,int> const& stuff = ( foo<int,int>() ) ); }; 

imo, these parenthesis necessary there additional requirement default argument can refer member of class may declared later in class body:

struct bar {   void method ( int = j);  // 'j' not declared yet   static const int j = 0; }; 

the above code legal, , when declaration 'method' being parsed member 'j' has not yet been seen. compiler therefore can parse default argument using syntax checking only, (ie. matching parenthesis , commas). when g++ parsing original declaration, seeing following:

void method ( foo<int,int> const& stuff = foo<int // arg 1 dflt.               , int>() );                         // arg 2 - syntax error 

adding set of parenthesis ensures default argument handled correctly.

the following case shows example g++ succeeds comeau still generates syntax error:

template<int j, int k> class foo { };  struct bar {   void method ( foo<0, 0> const & = ( foo<j, k> () ) );   static const int j = 0;   static const int k = 0; }; 

edit:

in response comment: "you have function call multiple arguments there", reason not cause problem comma's inside function call surrounded in parenthesis:

int foo (int, int, int); struct bar {   void method ( int j =                     foo (0, 0, 0) ); // comma's here inside ( ) }; 

it possible therefore, parse using syntax of expression only. in c++, '(' must matched ')' , easy parse. reason problem here '<' not need matched, since overloaded in c++ , can less operator or start of template argument list. following example shows '<' used in default argument , implies less operator:

template<int i, int j> class foo { };  struct bar {   template <typename t> struct y { };    void method ( ::foo<0,0> const& stuff = foo<10 , y < int >  = y<int>() );    struct x {     ::foo<0, 0> operator< (int);   };    static x foo; }; 

the above "foo<10" call "operator<" defined in 'x', not start of template argument list. again, comeau generates syntax errors on above code , g++ (including 3.2.3) parse correctly.

fyi, appropriate references note in 8.3.6/5:

[note: in member function declarations, names in default argument expressions looked described in 3.4.1...

and in 3.4.1/8

a name used in definition of member function (9.3) of class x following function’s declaratorid29) shall declared in 1 of following ways:

...

— shall member of class x or member of base class of x (10.2), or

this bullet here, part forces compiler "delay" lookup meaning of default argument until of class members have been declared.

<update>

as pointed out "employed russian", g++ 4.4 able parse of these examples. however, until dr has been addressed c++ standards committee not yet ready call "bug". believe long term parenthesis required ensure portability other compilers/tools (and maybe future versions of g++).

it has been experience c++ standard not dictate compiler vendors should use same parser technology , cannot expect technologies equally powerful. result, parsing requirements don't require vendors perform superhuman feats. illustrate consider following 2 examples:

typedef t::type type; t::type t; 

if 't' dependent, given each context 'type' must typename, standard still requires typename keyword. these examples unambiguous , can mean 1 thing, standard (in order allow parser technologies) still requires typename keyword.

it's possible dr may addressed in such way compiler fails parse these examples still "standard conforming" long parenthesis allows code parse.

</update>


Comments

Popular posts from this blog

windows - Single EXE to Install Python Standalone Executable for Easy Distribution -

c# - Access objects in UserControl from MainWindow in WPF -

javascript - How to name a jQuery function to make a browser's back button work? -