2017-12-18 72 views
0

我有三個文件 - 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): undefined reference to `void funcN(int, int, ...)' collect2: error: ld returned 1 exit status

我知道這個錯誤是因爲auto...,我知道我可以解決它,如果我在lib.h內部實現,但這看起來很討厭 - 在一個文件中實現一些實現,在另一個文件中實現其他實現。我想知道,他們如何在現實世界的實踐中做到這一點。

+6

您可能需要添加一個'-pedantic'標誌。 [這不是標準的C++](http://coliru.stacked-crooked.com/a/d55fca982f36d9ae)。它看起來像是將該功能轉換爲模板的擴展。還有,[模板更好地定義在標題中](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file)。 – StoryTeller

回答

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...不會聲明帶自動類型的參數包。它聲明一個未命名的參數,然後是常規省略號,因爲編譯器允許在elipses之前省略逗號。聲明它沒有auto如果你想獲得一個常規的可變參數函數

void funcN(int i, ...) 

或在頭文件合適的模板,如果你想獲得真正的參數包

template<typename... TArgs> void 
function(int i, TArgs... args) {} 
+2

在標準的C++中'auto'在所有參數聲明中都是不允許的,所以它並沒有真正定義任何東西(而且''auto ... j'中的省略號不能是常規的C樣式省略號,但是你可以旋轉它。這是一個gcc擴展,它確實意味着「帶有自動類型的參數包」。 –