Jacobian
Jacobian

Reputation: 10802

Parameter packs and function declaration

I have three files - lib.h with function declarations, lib.cpp with implementation and main.cpp entry point. Their contents is just as simple as:

//lib.h
#pragma once

void func1();
void func2();
void funcN();

//lib.cpp
#include "lib.h"

void func1(){}
void func2(){}
void funcN(){}

//main.cpp
#include "lib.h"

int main() {
    return 0;
}

I compile it like so:

$ g++ main.cpp lib.cpp

So far, so good. But now I want to use parameter pack in one of my functions. Like so:

//change in lib.cpp

void funcN(int i, auto... j) {

}

I change lib.h and main.cpp respectively:

//change in lib.h
void funcN(int, auto...);

//change in main.cpp

int main() {
    funcN(1, 2);
    return 0;
}

But now, when I compile it with

$ g++ main.cpp lib.cpp

I get this error message:

main.cpp:(.text+0x14): undefined reference to `void funcN(int, int, ...)' collect2: error: ld returned 1 exit status

I know that this error is because of auto... and I know that I can probably solve it, if I put implementation inside lib.h, but this looks nasty - to have some implementations in one file and other implementations in another. I would like to know, how they do it in real world practice.

Upvotes: 0

Views: 1088

Answers (2)

Vittorio Romeo
Vittorio Romeo

Reputation: 93264

Using auto as a function parameter is not Standard C++. Your code is currently not valid C++. See Is auto as a parameter in a regular function a GCC 4.9 extension? for more information. Note that auto as a function parameter (along with shorthand concept syntax) was not added to C++20's working draft yet.

Regardless, using auto in that manner is just shorthand for function template definition - this means that your need to define your function in the header.

Here's a solution that's valid C++:

// lib.h
template <typename... Js>
void funcN(int i, Js... js) {

}

More information: Why can templates only be implemented in the header file?

Upvotes: 5

user7860670
user7860670

Reputation: 37468

In this case auto... does not declare parameter pack with auto type. It declares an unnamed parameter followed by regular ellipsis because compiler allows to omit comma before elipses. Declare it without auto if you want to get a regular variadic function

void funcN(int i, ...)

Or as a proper template in header file if you want to get real parameter pack

template<typename... TArgs> void
function(int i, TArgs... args) {}

Upvotes: -1

Related Questions