летучая перегрузка?

Я слышал, что volatile является фактором перегрузки, как const.

Если функция перегружена volatile-параметром, когда вызывается volatile-версия?

Я не могу представить ситуацию, когда вызывается volatile-версия.


person Gimun Eom    schedule 20.04.2012    source источник
comment
Добавлен тег C++; если это не тот язык, о котором вы говорите, пожалуйста, отредактируйте свой вопрос, упомянув этот довольно важный факт, и отметьте его соответствующим образом.   -  person Mat    schedule 20.04.2012
comment
Это просто похоже на const. Если у вас есть квалифицированный объект volatile, то для него можно вызвать только функцию volatile.   -  person Alok Save    schedule 20.04.2012
comment
В общем, почти все, что относится к квалификаторам const, применимо и к квалификаторам volatile. В стандарте они чаще всего называются cv-qualifiers.   -  person Mike Seymour    schedule 20.04.2012
comment
Вот интересное использование (или, возможно, злоупотребление) volatile функций-членов для предоставления времени компиляции проверьте, что доступ к объекту осуществляется потокобезопасным способом. По сути, вы получаете доступ к разблокированным объектам через volatile ссылки и к заблокированным объектам через обычные ссылки, и каждая операция имеет volatile перегрузку, которая сначала получает блокировку.   -  person Mike Seymour    schedule 20.04.2012


Ответы (3)


Volatile можно применять к параметрам, но это не является фактором перегрузки при непосредственном применении к параметру. Однако его можно использовать для различения типов параметра. Например, это законно:

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 Перегружаемые объявления. Из черновика С++ 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 на самом внешнем уровне спецификации типа параметра; Константные и изменчивые спецификаторы типов, спрятанные в спецификации типа параметра, важны и могут использоваться для различения объявлений перегруженных функций124. В частности, для любого типа T pointer to T, pointer to const T и pointer to volatile T считаются отдельными типами параметров, как и reference to T, reference to const T и reference to volatile T.

124) Когда тип параметра включает в себя тип функции, например, в случае типа параметра, который является указателем на функцию, спецификаторы типа const и volatile на самом внешнем уровне спецификаций типа параметра для внутренней функции также игнорируются.

person Jirka Hanika    schedule 20.04.2012

Вот пример:

#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() было бы недействительным.

person Mat    schedule 20.04.2012
comment
Не так быстро. Кажется, этот вопрос касается изменчивых параметров, и они не являются фактором перегрузки. - person Jirka Hanika; 20.04.2012
comment
Мне это было (не) совсем ясно, и Пит уже опубликовал ответ о параметрах функции. - person Mat; 20.04.2012
comment
Меня это устраивает, но @Pete также не дает полного ответа. Может, нам стоит консолидироваться. - person Jirka Hanika; 20.04.2012
comment
Для этого я включил вашу хорошую мысль в принятый ответ и проголосовал за вас. - person Jirka Hanika; 20.04.2012
comment
Я включил цитату из стандарта в вашу, надеюсь, вы не возражаете :) - person Mat; 20.04.2012

Напишите тестовую программу, чтобы узнать.

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)
person Pete    schedule 20.04.2012