Search code examples
c++templatescompiler-errorsforward-declarationdefault-arguments

How to forward declare a template function in global or namespace with default argument?


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?


Solution

  • 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).