How to resolve the GCC error message "default argument for parameter of type ... has type ..."

Problem:

You encounter a GCC error message of the form

error: default argument for parameter of type <some type> has type <some other type>

Error source:

Somewhere in your code you have a function with a default argument like this:

void doSomething(int arg1, std::set<std::string> arg2 = 15) {/*...*/}

At least one of the arguments to that function have default arguments (in the example above, only arg2 has a default value) that doesn’t match its type (in other words, the argument type can’t be initialized with the given default value).

In the example listed above, arg2, which has the type std::set<std::``string> would be initialized to the number 15 if doSomething``() is called with only one argument. Of course ,it doesn’t make any sense to initialize a std::set<std::string``> with a number. **Note:**Most STL containers have a constructor that can be called with a single integer-like argument (initializing them with a given size or capacity), but std::set does not!

Identifying the cause

Usually the file and the line number in the error message denotes the position of the function causing the error. However, If the function causing the error is a template function, usually the line of the function call (and the corresponding file) is listed in the error message. The file and the line where the template function is declared is usually not visible in the error log, so don’t get confused by this.

This error is always caused by a incorrect function declaration and not by the code inside the parentheses of the functions (C++11 lambda functions may also cause this error).

Resolving the error

Check all default arguments in your function declaration. Maybe one looks suspicious - if not, do the following for each default argument:

Check if the type of the function has a constructor that can be called with the given types. If it doesn’t have such a constructor, replace it by a valid default argument.

If this doesn’t work, replace the default arguments by alternatives one after another.e

Possible caveat: Constructors declared using the explicit keyword need to be called explicitly in the default argument (also see the special case below).

In some cases this error can also be caused by a reference being initialized like a value. If the solutions above don’t solve the problem, try removing the & from the argument type!

Special case

I once encountered this strange error message:

error: default argument for parameter of type `std::string& {aka std::basic_string<char>&}' has type `const char [1]'

It was caused by a template function like this:

template<typename T> void doSomething(std::string arg = "") {/*...*/}

It turns out that gcc can’t interpret that correctly ("" should initialize an empty string - apparently it works if it isn’t a template function).

Replacing the declaration by

template<typename T> void doSomething(std::string arg = std::string()) {/*...*/}

worked. If you don’t want an empty string as default, you could use a declaration like this (using explicit constructor calls)

template<typename T> void doSomething(std::string arg = std::string("abc")) {/*...*/}

You also need to use a construct like that if you want to use an explicit constructor (= constructor declared using the explicit keyword).