2017-06-12 72 views
-5

在我的代碼中,我有一個std ::函數,它將在運行時根據用戶輸入定義,其他文件稍後將調用此函數。一個最小的(不)工作的代碼的例子如下:包含在多個文件中時std :: function對象有多個定義錯誤?

在my_func.h文件,我有:

#pragma once 
#include <iostream> 
#include <functional> 

std::function<int(int)> inc_step; 

void SetIncFunc(); 

在my_func.cpp:

#include "my_func.h" 
void SetIncFunc() { 
    std::cout << "Input a number!" << std::endl; 
    int input; 
    std::cin >> input; 
    inc_step = [input](int x) {return x + input; }; 
} 

最後,在main.cpp中:

#include "my_func.h" 
int main() { 
    SetIncFunc(); 
    int x = 0; 
    std::cout << "before incrementing: " << x << std::endl; 
    x = inc_step(x); 
    std::cout << "after incrementing: " << x << std::endl; 
    return 0; 
} 

g ++連接器會給出如下錯誤:「inc_step'的多重定義」。 (也嘗試在Visual Studio中,類似的錯誤)但是,如果我將所有代碼移動到main.cpp文件中,那麼它將編譯並正確運行。

我很困惑,因爲的#pragma一次應該阻止多個包裹,我只定義在SetIncFunc()函數...所以是有一個特殊的規則,包括的std ::函數對象?

在此先感謝!

+0

'#一次只編譯一次'#include'sa頭文件,每次編譯。這與重複的頭文件包含無關。 –

+0

你嘗試過'extern'嗎? –

+1

與'std :: function'無關。 – juanchopanza

回答

1

這是一個ODR違反定義頭像這樣的變量。在C++ 17可以將其標記inline解決這一問題,但在舊版本,你需要有頭包含:

extern std::function<int(int)> inc_step; 

而源文件只有一個包含:

std::function<int(int)> inc_step;