0

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.

Jacobian
  • 10,122
  • 29
  • 128
  • 221
  • 6
    You may want to add a `-pedantic` flag. [It's not standard C++](http://coliru.stacked-crooked.com/a/d55fca982f36d9ae). It seem like an extension that transforms that function into a template. And well, [a template better be defined in a header](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file). – StoryTeller - Unslander Monica Dec 18 '17 at 08:45

2 Answers2

5

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?

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
-1

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) {}
user7860670
  • 35,849
  • 4
  • 58
  • 84
  • 2
    In standard C++ `auto` is not allowed in a parameter declaration at all, so it doesn't really define anything (and the ellipsis in `auto ... j` cannot be a regular C style ellipsis however you spin it). It's a gcc extension, and it does mean "parameter pack with auto type". – n. m. could be an AI Dec 18 '17 at 08:55