Reputation: 10802
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
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
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