Аргумент по умолчанию в середине списка параметров?
Я видел объявление функции в нашем коде, которое выглядело следующим образом
void error(char const *msg, bool showKind = true, bool exit);
сначала я подумал, что это ошибка, потому что у вас не может быть аргументов по умолчанию в середине функций, но компилятор принял это объявление. Кто-нибудь видел это раньше? Я использую версии gcc4.5. Это расширение GCC?
странная вещь, если я беру это в отдельный файл и пытаюсь скомпилировать, GCC отклоняет его. Я дважды проверил все, включая компилятор используемые параметры.
2 ответа:
этот код будет работать, если в самом первом объявлении функции последний параметр имеет значение по умолчанию, что-то вроде этого:
//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.
ответ может быть в 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
прочитав это, я обнаружил, что 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"); }