我听说volatile是像const一样的重载因素。
如果函数被volatile参数重载, 什么时候是volatile-version叫?
我无法想象调用volatile-version时的情况。
答案 0 :(得分: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()
将无效。
答案 1 :(得分: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) {};
原因是在第一个例子中,引用不是volatile,而是整数。在第二个示例中,两种类型都是整数,因此类型相同。
还有一些不稳定的方法。它们类似于声明this
是不稳定的。因为this
是指针而不是包含类型本身,所以以下内容也是合法的:
void c::f(int p) {};
void c::f(int p) volatile {};
与const
的重载完全相同。
C ++标准的相关部分是§13.1可重载声明。来自C ++ 11 draft 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类型说明符很重要,可用于区分重载函数声明 124 。特别是,对于任何类型T,
pointer to T
,pointer to const T
和pointer to volatile T
被视为不同的参数类型,reference to T
,reference to const T
和{{1}也是如此}}124)当参数类型包括函数类型时,例如在参数类型是指向函数的指针的情况下, 内部函数类型的参数类型规范的最外层的const和volatile类型说明符是 也被忽略了。
答案 2 :(得分: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)