Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

volatile overloading?

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. 

like image 405
Gimun Eom Avatar asked Apr 20 '12 08:04

Gimun Eom


3 Answers

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.

like image 107
Mat Avatar answered Nov 15 '22 19:11

Mat


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, and pointer to volatile T are considered distinct parameter types, as are reference to T, reference to const T, and reference 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.

like image 26
Jirka Hanika Avatar answered Nov 15 '22 19:11

Jirka Hanika


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)
like image 22
Pete Avatar answered Nov 15 '22 21:11

Pete