我有三个文件 - 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;
}
Run Code Online (Sandbox Code Playgroud)
我这样编译它:
$ g++ main.cpp lib.cpp
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是现在我想在我的一个函数中使用参数包.像这样:
//change in lib.cpp
void funcN(int i, auto... j) {
}
Run Code Online (Sandbox Code Playgroud)
我分别改变了lib.h和main.cpp:
//change in lib.h
void funcN(int, auto...);
//change in main.cpp
int main() {
funcN(1, 2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但现在,当我编译它时
$ g++ main.cpp lib.cpp
Run Code Online (Sandbox Code Playgroud)
我收到此错误消息:
main.cpp :(.text + 0x14):未定义引用`void funcN(int,int,...)'collect2:error:ld返回1退出状态
我知道这个错误是因为auto...我知道我可以解决它,如果我把实现放在里面lib.h,但这看起来很讨厌 - 在一个文件中有一些实现,在另一个文件中有其他实现.我想知道,他们是如何在现实世界中练习的.
使用auto作为函数参数是不标准C++.您的代码目前无效C++.请参阅GCC 4.9扩展的常规功能中的自动是否为参数?欲获得更多信息.请注意,auto作为函数参数(以及速记概念语法)尚未添加到C++ 20的工作草案中.
无论如何,auto以这种方式使用只是函数模板定义的简写 - 这意味着您需要在标题中定义函数.
这是一个有效的C++解决方案:
// lib.h
template <typename... Js>
void funcN(int i, Js... js) {
}
Run Code Online (Sandbox Code Playgroud)
更多信息:为什么模板只能在头文件中实现?