参数包和函数声明

时间:2017-12-18 08:41:46

标签: c++

我有三个文件 - 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中,但这看起来很讨厌 - 在一个文件中有一些实现另一个实现。我想知道,他们是如何在现实世界中练习的。

2 个答案:

答案 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) {}