2012-04-20 54 views
10

我聽說volatile是const的重載因素。易失性超載?

如果一個函數被volatile參數重載, when是什麼時候volatile的版本被調用?

我無法想象當調用volatile版本時的情況。  

+0

添加C++標籤;如果這不是你正在談論的語言,請編輯你的問題以提及相當重要的事實並適當地重新標記。 – Mat 2012-04-20 08:17:17

+2

這與'const'類似,如果你有一個'volatile'限定對象,那麼只能調用'volatile'函數。 – 2012-04-20 08:19:48

+1

哦,我滑了我的腦海 – 2012-04-20 08:25:53

回答

8

可以將揮發性數據應用於參數,但當直接應用於參數時,它不是過載的因素。但是可以使用它來區分參數的類型。例如,這是合法的:

void f(int &p) {}; //reference to int 
void f(volatile int &p) {}; //reference to volatile int 

這不是:

void f(int p) {}; 
void f(volatile int p) {}; 

的原因是,在第一個例子引用是不是有什麼波動,但整數。在第二個例子中,兩種類型都是整數,因此是相同的類型。

也有不穩定的方法。他們類似於宣稱this是易變的。由於this是一個指針,而不是包含類型本身,下面的內容也是合法的:

void c::f(int p) {}; 
void c::f(int p) volatile {}; 

它是所有相同的const超載。

C++標準的相關部分是§13.1可重載聲明。來自C++ 11草案n3290:

參數聲明僅在存在或不存在const和/或volatile時是相同的。也就是說,在確定哪個函數正在被聲明,定義或調用時,忽略每個參數類型的const和volatile類型說明符。 [實施例:

typedef const int cInt; 
int f(int); 
int f(const int);   // redeclaration of f(int) 
int f(int) { /* ... */ } // definition of f(int) 
int f(cInt) { /* ... */ } // error: redefinition of f(int) 

- 端示例]

只有在參數類型規範的最外層的const和volatile類型說明符以這種方式被忽略;隱藏在參數類型規範中的const和volatile類型說明符是重要的,可用於區分重載函數聲明。特別地,對於任何類型的T,pointer to Tpointer to const T,和pointer to volatile T被認爲是不同的參數類型,因爲是reference to Treference to const T,和reference to volatile T

124)當參數類型包括功能類型,例如在參數類型的情況下是一個指向功能, const和volatile類型說明符在參數類型規格的用於最外層平內部功能類型 也被忽略。

+0

這是一個很好的答案 – Pete 2012-04-20 12:43:40

10

下面是一個例子:

#include <iostream> 

struct A { 
    void foo() { 
     std::cout << "in non-volatile" << std::endl; 
    } 
    void foo() volatile { 
     std::cout << "in volatile" << std::endl; 
    } 
}; 

int main() 
{ 
    A a; 
    a.foo(); 
    volatile A b; 
    b.foo(); 
} 

b.foo()將調用volatile超載。如果struct A對於foo沒有易失性過載,則b.foo()將無效。

+0

沒那麼快。這個問題似乎是關於易失性參數,而這些不是超載的一個因素。 – 2012-04-20 08:51:43

+0

這並不完全清楚 - 皮特已經發布了關於函數參數的答案。 – Mat 2012-04-20 08:55:05

+0

我很好,但@Pete也沒有給出完整的答案。也許我們應該鞏固。 – 2012-04-20 09:29:50

3

寫一個測試程序找出來。

void func(const int& a) 
{ 
    std::cout << "func(const)" << std::endl; 
} 

void func(const volatile int& a) 
{ 
    std::cout << "func(const volatile)" << std::endl; 
} 

int main() 
{ 
    const int a = 0; 
    const volatile int b = 0; 
    func(a); 
    func(b); 
    system("pause"); 
    return 0; 
} 

將輸出:

func(const) 
func(const volatile)