I heard that volatile is factor of overloading like const.
If a function is overloaded by volatile parameter, when is the volatile-version called?
I can't imagine a situation when the volatile-version is called.
Here's an example:
#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()
will call the volatile
overload. If struct A
didn't have a volatile overload for foo
, b.foo()
would be invalid.
Volatile can be applied to parameters, but it is not a factor of overloading when applied directly to the parameter. It is however possible to use it to distinguish types of the parameter. For example, this is legal:
void f(int &p) {}; //reference to int
void f(volatile int &p) {}; //reference to volatile int
This is not:
void f(int p) {};
void f(volatile int p) {};
The reason is that in the first example the reference is not what is volatile, but the integer. In the second example, both types are integers and therefore the same type.
There are also volatile methods. They are akin to declaring this
to be volatile. Because this
is a pointer and not the containing type itself, the following is also legal:
void c::f(int p) {};
void c::f(int p) volatile {};
It is all the same as for overloading by const
.
This relevant part of the C++ standard is §13.1 Overloadable declarations. From C++11 draft n3290:
Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called. [ Example:
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)
— end example ]
Only the const and volatile type-specifiers at the outermost level of the parameter type specification are ignored in this fashion; const and volatile type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations124. In particular, for any type T,
pointer to T
,pointer to const T
, andpointer to volatile T
are considered distinct parameter types, as arereference to T
,reference to const T
, andreference to volatile T
.124) When a parameter type includes a function type, such as in the case of a parameter type that is a pointer to function, the const and volatile type-specifiers at the outermost level of the parameter type specifications for the inner function type are also ignored.
Write a test program to find out.
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;
}
will output:
func(const)
func(const volatile)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With