2015-11-04 44 views
0

下面的代碼不違反一個定義規則,但它給了意想不到的結果:C++內聯函數,並具有相同名稱的外部函數給出一個意想不到的結果

Test.hpp

class Test 
{ 
    public: 
     int test(); 
}; 

Test1.cpp

#include "Test.hpp" 

int Test::test() 
{ 
    return 1; 
} 

int test1() // expected to return 1 
{ 
    Test a = Test(); 
    return a.test(); 
} 

測試2.cpp

#include "Test.hpp" 

inline int Test::test() // doesn't violate ODR 
{ 
    return 99; 
} 

int test2() // expected to return 99 
{ 
    Test a = Test(); 
    return a.test(); 
} 

的main.cpp

#include <iostream> 

int test1(); 
int test2(); 

int main() 
{ 
    std::cout << test1() << std::endl; 
    std::cout << test2() << std::endl; 
} 

我期待它打印 「1 99」,但它總是打印 「1 1」。

關於Test :: test的兩個定義,由於它們中的一個是內聯定義,所以它也不違反One Definition Rule。

所以這個方案是有效的,但它不是打印出預期的結果...

有什麼不對這個計劃?還是我誤解了一些關於ODR規則的東西? (對C++標準的引用會很有幫助)。

+1

'關於測試::測試的兩個定義,因爲他們中的一個是內聯函數,它不違反ODR'你從哪裏得到這個理念? – bolov

+0

嗯,我認爲它沒有違反ODR,因爲在C++規範的ODR部分中沒有提到這個問題。 「如果具有外部鏈接的功能在一個翻譯單元中聲明爲內聯,則應在其出現的所有翻譯單元中聲明爲內聯;不需要診斷。」在函數說明符部分提到,它不涉及ODR。 – SHH

回答

3

您不能將該功能定義爲inline和非inline

如果具有外部鏈接的功能 在一個翻譯單元中聲明的內聯,應當內嵌在其中出現所有翻譯單元聲明; 不需要診斷。

([dcl.fct.spec/4)

+0

感謝您的回答。但是您提到的聲明並未在規範的ODR部分中說明。那麼我可以說我提供的代碼不違反ODR嗎? (它違反了函數說明符規則,但不是ODR) – SHH

+0

@SHH我不能說它是否有效。 ODR的措辭具有「非內聯功能」。因此它隱含地假設一個函數不能既是內聯也是非內聯的;它必須是一個或另一個。當您試圖聲明同時使用內聯和非內聯函數時,ODR甚至沒有意義。 – Brian

相關問題