参数包和函数声明

问题描述 投票:0回答:2

我有三个文件 - 带有函数声明的lib.h,带有实现的lib.cppmain.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:error:ld返回1退出状态

我知道这个错误是因为auto...而且我知道我可以解决它,如果我把实现放在lib.h中,但这看起来很讨厌 - 在一个文件中有一些实现,在另一个文件中有其他实现。我想知道,他们是如何在现实世界中练习的。

c++
2个回答
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
投票

在这种情况下,auto...不会声明带有自动类型的参数包。它声明了一个未命名的参数,后跟常规省略号,因为编译器允许在省略之前省略逗号。如果你想获得一个常规的可变参数函数,则在没有auto的情况下声明它

void funcN(int i, ...)

或者作为头文件中的正确模板,如果你想获得真正的参数包

template<typename... TArgs> void
function(int i, TArgs... args) {}
© www.soinside.com 2019 - 2024. All rights reserved.