template<typename T> void foo (T t, int i = 0); // declaration
int main () { foo(1, 0); } // error!!
template<typename T> void foo (T t, int i = 0) {} // definition
Above is a minimal reproducible example for a larger problem, where many header files are involved. Attempting to forward declare with default parameter results in below compilation:
error: redeclaration of ‘template void foo(T, int)’ may not have default arguments [-fpermissive]
How to fix this?
CodePudding user response:
A default argument, like int i = 0
, is seen as a definition. Repeating it is therefore an ODR-violation.
Don't know exactly why, except that the standard explicitly says so
Each of the following is termed a definable item:
[...]
(1.6) a default argument for a parameter (for a function in a given > scope)
[...] No translation unit shall contain more than one definition of any definable item.
http://eel.is/c draft/basic.def.odr
The solution is then to only have the default argument appear once, likely in the declaration (and not repeated in the definition).