Palace Chan
Palace Chan

Reputation: 9183

Default container arguments

The following header works with the commented part as expected when I call the function bat with no arguments:

class Test
{
 public:

  void bat(std::vector<int> k = std::vector<int>()) {}
  //void cat(std::map<int, std::vector<int> > k = std::map<int, std::vector<int> >()) {}

};

But when I try using the cat function in the header:

class Test
{
 public:

  void bat(std::vector<int> k = std::vector<int>()) {}
  void cat(std::map<int, std::vector<int> > k = std::map<int, std::vector<int> >()) {}

};

I get:

test.h:14: error: expected ',' or '...' before '>' token
test.h:14: error: wrong number of template arguments (1, should be 4)
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_map.h:92: error: provided for 'template<class _Key, class _Tp, class _Compare,\
 class _Alloc> class std::map'
test.h:14: error: default argument missing for parameter 2 of 'void Test::cat(std::map<int, std::vector<int, std::allocator<int> >, std::less<int>, std::all\
ocator<std::pair<const int, std::vector<int, std::allocator<int> > > > >, std::vector<int, std::allocator<int> >)'

How come? And are there easy workarounds for this? hopefully not requiring a pointer type change in the interface?

This is my full header:

#ifndef TEST_H
#define TEST_H

#include <map>
#include <vector>
#include <sstream>
#include <iostream>

class Test
{
 public:

  //void bat(std::vector<int> k = std::vector<int>()) {}
  void cat(std::map<int, std::vector<int> > k = std::map<int, std::vector<int> >()) {}

};


#endif

so all the right includes are there. My version of GCC is terribly outdated (well not at home, ill try it at home too) - but at work it's 4.1.2

Upvotes: 0

Views: 1810

Answers (4)

Jonathan Wakely
Jonathan Wakely

Reputation: 171263

This is C++ core Defect Report 325 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#325

GCC 4.4 implements the suggested (but not yet official) resolution of the DR, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57#c36

Upvotes: 0

Node
Node

Reputation: 3509

From the other posts here, it looks like it could be a compiler problem, in which case, you can get around it by using a typedef instead of the map type directly.

#include <vector>
#include <map>

class Test
{
 public:
  typedef std::map<int, std::vector<int> > MyMap;

  void bat(std::vector<int> k = std::vector<int>()) {}
  void cat(MyMap k = MyMap()) {}

};

int main()
{
}

Upvotes: 0

juanchopanza
juanchopanza

Reputation: 227370

The code looks OK, but fails on gcc 4.3.4, see here, but compiles fine with 4.6 onwards (I haven't tested 4.4 or 4.5). So it looks like the workaround is to use a newer gcc.

#include <map>
#include <vector>

class Test
{
 public:

  void bat(std::vector<int> k = std::vector<int>()) {}
  void cat(std::map<int, std::vector<int> > k = std::map<int, std::vector<int> >
()) {}

};

int main() {

}

Concerning default parameters, it may be an idea to drop them altogether:

class Test {
 public:

  void bat(std::vector<int> k) {}
  void bat() {}
  void cat(std::map<int, std::vector<int> > k) {}
  void cat() {}
};

otherwise, you couple the default parameters to the interface, meaning you cannot change them without requiring re-compilation of all client code.

Upvotes: 4

John Dibling
John Dibling

Reputation: 101446

The code you've posted seems fine, so I'm going to turn on my Psychic Debugger module.

Did you:

#include <vector>

...in your header?

Upvotes: 0

Related Questions