0

I just extracted the following problem in our project. The following code just compiles fine with g++

#include <vector>

class A {};

typedef std::vector<A*> vec_t;

class bar {
public:
  bar(vec_t) {};
};

class foo
{
public:
  foo(bar* a = new bar(vec_t())) {};
};

class B
{};

int main()
{
  return 0;
}

However, the Visual Studio Compiler (VC12, but I presume all others too) doesn't understand that in the default argument for the c'tor of foo the c'tor of bar is called which takes an instance of a vector as an argument. This causes an error for every class/struct declared after this expression:

error C2462: 'B' : cannot define a type in a 'new-expression'

I don't want to discuss the software design of the c'tor, but is this a compiler issue or just not allowed in standard C++ and the g++ just not being strict about that?

First, I thought that a template-instantiation in a default parameter may be not allowed or nested c'tors in a default argument. However, if I use another c'tor of the vector:

foo(bar* a = new bar(vec_t(0))) {}

it compiles with MSVC. I just can't see why the upper version shouldn't compile? Any thoughts on that?

1 Answers1

0

It looks like this is an issue with the "most vexing parse" (see the Wikipedia article on it for more info). One way to disambiguate the new expression is to add parentheses around the constructor like this

foo(bar* a = new bar((vec_t()))) {};

When it comes to standards compliance I'm not sure. I skimmed section 6.8 (Ambiguity Resolution) and 5.3.4 (New) of N3690 and without thinking about it too hard nothing stood out either way. Maybe a real language lawyer will need to step in to give an answer.

Rastaban
  • 881
  • 6
  • 8