Аргумент по умолчанию в середине списка параметров?
Я видел в нашем коде объявление функции, которое выглядело следующим образом
void error(char const *msg, bool showKind = true, bool exit);
Сначала я подумал, что это ошибка, потому что вы не можете иметь аргументы по умолчанию в середине функций, но компилятор принял это выражение. Кто-нибудь видел это раньше? Я использую GCC4.5. Это расширение GCC?
Странно, если я возьму это в отдельном файле и попытаюсь скомпилировать, GCC отвергает его. Я дважды проверил все, включая используемые параметры компилятора.
Ответы
Ответ 1
Этот код будет работать, если в самом первом объявлении функции последний параметр имеет значение по умолчанию, примерно следующее:
//declaration
void error(char const *msg, bool showKind, bool exit = false);
И затем в той же области действия вы можете предоставить значения по умолчанию для других аргументов (с правой стороны) в более позднем объявлении:
void error(char const *msg, bool showKind = true, bool exit); //okay
//void error(char const *msg = 0 , bool showKind, bool exit); // error
который может быть вызван как:
error("some error messsage");
error("some error messsage", false);
error("some error messsage", false, true);
Онлайн-демонстрация: http://ideone.com/aFpUn
Обратите внимание, что если вы указали значение по умолчанию для первого параметра (слева), не указав значение по умолчанию для второго, оно не будет компилироваться (как ожидалось): http://ideone.com/5hj46
В §8.3.6/4 говорится:
Для не-шаблонных функций по умолчанию аргументы могут быть добавлены позже объявления функции в том же сфера.
Пример из самого стандарта:
void f(int, int);
void f(int, int = 7);
Второе объявление добавляет значение по умолчанию!
Также см. §8.3.6/6.
Ответ 2
Ответ может быть в 8.3.6:
8.3.6 Аргументы по умолчанию
6 За исключением функций-членов класса шаблонов, аргументы по умолчанию в определение функции члена, появляется вне класса определение добавляются в набор аргументы по умолчанию, предоставленные объявление функции-члена в определение класса. По умолчанию аргументы для функции-члена класса шаблон должен быть указан на первоначальная декларация члена функции внутри шаблона класса. [Пример:
class C {
void f(int i = 3);
void g(int i, int j = 99);
};
void C::f(int i = 3) // error: default argument already
{ } // specified in class scope
void C::g(int i = 88, int j) // in this translation unit,
{ } // C::g can be called with no argument
-end пример]
После прочтения этого, я обнаружил, что MSVC10 принял следующее с отключенными расширениями компилятора:
void error(char const* msg, bool showKind, bool exit= false);
void error(char const* msg, bool showKind = false, bool exit)
{
msg;
showKind;
exit;
}
int main()
{
error("hello");
}