Я слышал, что volatile является фактором перегрузки, как const.
Если функция перегружена volatile-параметром, когда вызывается volatile-версия?
Я не могу представить ситуацию, когда вызывается volatile-версия.
Я слышал, что volatile является фактором перегрузки, как const.
Если функция перегружена volatile-параметром, когда вызывается volatile-версия?
Я не могу представить ситуацию, когда вызывается volatile-версия.
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 на самом внешнем уровне спецификаций типа параметра для внутренней функции также игнорируются.
Вот пример:
#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()
было бы недействительным.
Напишите тестовую программу, чтобы узнать.
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)
const
. Если у вас есть квалифицированный объектvolatile
, то для него можно вызвать только функциюvolatile
. - person Alok Save   schedule 20.04.2012const
, применимо и к квалификаторамvolatile
. В стандарте они чаще всего называются cv-qualifiers. - person Mike Seymour   schedule 20.04.2012volatile
функций-членов для предоставления времени компиляции проверьте, что доступ к объекту осуществляется потокобезопасным способом. По сути, вы получаете доступ к разблокированным объектам черезvolatile
ссылки и к заблокированным объектам через обычные ссылки, и каждая операция имеетvolatile
перегрузку, которая сначала получает блокировку. - person Mike Seymour   schedule 20.04.2012