我有三个文件 - lib.h
带有函数声明,lib.cpp
带有实现和main.cpp
入口点。他们的内容就像:
//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;
}
我这样编译:
$ g++ main.cpp lib.cpp
到目前为止,这么好。但是现在我想在我的一个函数中使用参数包。像这样:
//change in lib.cpp
void funcN(int i, auto... j) {
}
我分别改变了lib.h和main.cpp:
//change in lib.h
void funcN(int, auto...);
//change in main.cpp
int main() {
funcN(1, 2);
return 0;
}
但现在,当我用
编译它时$ g++ main.cpp lib.cpp
我收到此错误消息:
main.cpp :(。text + 0x14):未定义引用`void funcN(int,int,...)' collect2:错误:ld返回1退出状态
我知道这个错误是因为auto...
并且我知道我可以解决它,如果我将实现放在lib.h
中,但这看起来很讨厌 - 在一个文件中有一些实现另一个实现。我想知道,他们是如何在现实世界中练习的。
答案 0 :(得分:5)
使用auto
作为函数参数不标准C ++。您的代码目前无效C ++。有关详细信息,请参阅Is auto as a parameter in a regular function a GCC 4.9 extension?。请注意,auto
作为函数参数(以及速记概念语法)尚未添加到C ++ 20的工作草案中。
无论如何,以这种方式使用auto
只是功能模板定义的简写 - 这意味着您需要在标题中定义您的函数。
这是一个有效的C ++解决方案:
// lib.h
template <typename... Js>
void funcN(int i, Js... js) {
}
更多信息:Why can templates only be implemented in the header file?
答案 1 :(得分:-1)
在这种情况下,auto...
不会声明带有自动类型的参数包。它声明了一个未命名的参数,后跟常规省略号,因为编译器允许在省略之前省略逗号。如果你想获得常规的可变参数函数
auto
的情况下声明它
void funcN(int i, ...)
如果您想获得真正的参数包
,或者作为头文件中的正确模板template<typename... TArgs> void
function(int i, TArgs... args) {}