Я просто извлек следующую проблему в нашем проекте. Следующий код просто прекрасно компилируется с 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;
}
Однако компилятор Visual Studio (VC12, но я предполагаю, что все остальные тоже) не понимает этого в аргументе по умолчанию для c’or of Foo негодяй бар называется, который принимает экземпляр вектора в качестве аргумента. Это вызывает ошибку для каждого класса / структуры, объявленной после этого выражения:
error C2462: 'B' : cannot define a type in a 'new-expression'
Я не хочу обсуждать программный дизайн c’tor, но это проблема компилятора или просто не разрешена в стандарте C ++, а g ++ просто не строг в этом отношении?
Во-первых, я подумал, что создание экземпляра шаблона в параметре по умолчанию может быть запрещено, или вложенные c’ors в аргументе по умолчанию. Однако, если я использую другой c’tor вектора:
foo(bar* a = new bar(vec_t(0))) {}
компилируется с MSVC. Я просто не понимаю, почему верхняя версия не должна компилироваться? Есть мысли по этому поводу?
Похоже, что это проблема «самого неприятного анализа» (см. Википедия статья об этом для получения дополнительной информации). Одним из способов устранения неоднозначности нового выражения является добавление скобок вокруг конструктора, например:
foo(bar* a = new bar((vec_t()))) {};
Когда дело доходит до соответствия стандартам, я не уверен. Я снял раздел 6.8 (Разрешение неоднозначности) и 5.3.4 (Новый) N3690 и не думая об этом слишком сильно, ничто не выделялось в любом случае. Может быть, реальный языковой адвокат должен будет вмешаться, чтобы дать ответ.
Других решений пока нет …