Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Объясните про volatile


Автор: borisbn 9.10.2011, 15:03
Всем привет!

На ИРКе задали такой вопрос: как заставить работать шаблонную версию
Код

template<size_t N>
void size(const char(&arr)[N]) {
    cout << "ref " << N << endl;
}
void size(const char* arr) {
    cout << "pointer" << endl;
}

size("foo");

http://liveworkspace.org/code/c604f09278a1ec1c504bacd89ad94f5c

Ответ меня несколько обескуражил:
Код

template<size_t N>
void size(const char(&arr)[N]) {
    cout << "ref " << N << endl;
}
void size(const volatile char* arr) { // <------ (volatile)
    cout << "pointer" << endl;
}

size("foo");

http://liveworkspace.org/code/44b1abd0c7249218ec498ad7c8681910

Можете объяснить, каким образом volatile не даёт работать второй ф-ции, когда вызывается size("foo"); ?
Спасибо.

P.S. ИРКа англоязычная, и выяснять там сложнее, чем на великом и могучем
P.P.S. Интересно услышать мнение тёзки сабжа smile

Автор: azesmcar 9.10.2011, 15:32
borisbn

Цитата(borisbn @  9.10.2011,  15:03 Найти цитируемый пост)
Можете объяснить, каким образом volatile не даёт работать второй ф-ции, когда вызывается size("foo"); ?

Точно также, как и любой другой квалификатор. Компилятор не находит более подходящую перегрузку и вызывает ее.
Конкретно в твоем примере при первом вызове срабатывает версия с массивом, так-как "foo" это массив символов, а во втором случае тип const char*.
volatile просто делает перегрузку менее подходящей для вызова. Хотя на самом деле я сильно сомневаюсь в правильности такого решения.
И вообще volatile не для того создан.

Автор: borisbn 9.10.2011, 15:54
Цитата(azesmcar @  9.10.2011,  15:32 Найти цитируемый пост)
volatile просто делает перегрузку менее подходящей для вызова

то, что рейтинг функции с const char * стал меньше для выбора - я понял. Не понял как на это повлиял volatile  smile 

Цитата(azesmcar @  9.10.2011,  15:32 Найти цитируемый пост)
Хотя на самом деле я сильно сомневаюсь в правильности такого решения.

однозначно, решение  какое-то ...мммм... странное. Я бы его не использовал. Просто стало интересно и захотелось разобраться почему так происходит

Автор: volatile 9.10.2011, 19:34
Цитата(azesmcar @  9.10.2011,  15:32 Найти цитируемый пост)
так-как "foo" это массив символов

Все-же, формально, это не совсем массив символов. Потому-что если явно задать массив, то волатайл не нужен.
http://liveworkspace.org/code/9ad72a5df592e48ade639ea8a02245ad


Цитата(borisbn @  9.10.2011,  15:03 Найти цитируемый пост)
Интересно услышать мнение тёзки сабжа 

Все эти приоритеты при неявном приведении, тёмная сторона С++. имхо, и еще раз имхо...

Автор: mes 9.10.2011, 22:32
Цитата(volatile @  9.10.2011,  18:34 Найти цитируемый пост)
Все-же, формально, это не совсем массив символов. 

формально говоря, это совсем не массив  символов smile 

Автор: borisbn 9.10.2011, 22:36
и всё же... каким образом этот
Цитата(mes @  9.10.2011,  22:32 Найти цитируемый пост)
совсем не массив  символов

попадает в ф-цию, ожидающую массив символов, если к указателю добавить volatile? не понимаю

Автор: volatile 9.10.2011, 23:34
Цитата(mes @  9.10.2011,  22:32 Найти цитируемый пост)
формально говоря, это совсем не массив  символов   

mes, а что это?

borisbn, мой пример не совсем корректный. я там забыл const поставить.
А если его поставить, то все меняется...
http://liveworkspace.org/code/abfc4931bd805633c7ed845d79a235e1
 smile 

Автор: volatile 9.10.2011, 23:52
Короче, открыл щаз студию.

Код:
Код

#include <iostream>
using namespace std;

template<size_t N>
void size(const char(&arr)[N])
{
    cout << "ref " << N << endl;
}
void size(const /*volatile */char* arr)
{
    cout << "pointer" << endl;
}

int main()
{
    char arr [] = "foo";
    size(arr);
    const char * foo = "foo";
    size(foo); 
} 

MS VC2008 выход:
Цитата

pointer
pointer


gcc (liveworkspace.org) выход:
Цитата

ref 4
pointer


На лицо явно баг! Но чей?, кто из них врёт? Здесь явно не может быть "имплементейшн дефайнед"

Автор: volatile 10.10.2011, 00:17
borisbn, Ваш код из первого поста http://liveworkspace.org/code/44b1abd0c7249218ec498ad7c8681910
На студии также ведет себя не так как gcc
студия выход:
Цитата

pointer
pointer


Добавлено через 4 минуты и 11 секунд
Вообще, мое мнение такое (и пусть меня закидают помидорами).
Шаблонная функция всегда, по правилам С++, имеет меньший приоритет перед явной.

Посему - это всего лишь баг gcc, и волотайл, здесь не спасет... (могу ошибаться)

Автор: math64 10.10.2011, 08:20
Кроме того,
Код

template<size_t N>
void size(const char arr[N])
{
    cout << "array" << N << endl;
}
template<size_t N>
void size(const char (&arr)[N])
{
    cout << "rarray" << N << endl;
}
void size(const char* arr) {
    cout << "сpointer" << endl;
}
void size(char* arr) {
    cout << "pointer" << endl;
}
void main()
{
size("foo");
char foo[] = "foo";
size(foo);
const char cfoo[] = "cfoo";
size(cfoo);
}

gcc:
cpointer
pointer
cpointer
Закомментарить void size(char* arr)
cpointer
rarray 4
cpointer
В size(const char arr[N]) - никогда не попадаем

Автор: azesmcar 10.10.2011, 08:54
Цитата(mes @  9.10.2011,  22:32 Найти цитируемый пост)
формально говоря, это совсем не массив  символов smile  

Цитата

2.13.4 String literals

An ordinary string literal has type “array of n const char” and static storage duration...


Цитата(borisbn @  9.10.2011,  15:54 Найти цитируемый пост)
Не понял как на это повлиял volatile  

квалификатор volatile как и const является частью сигнатуры функции и участвует в выборе перегрузки (или как там переводиться overload resolution?).
Цитата

1.3.10 signature

the information about a function that participates in overload resolution (13.3): the types of its parameters
and, if the function is a class member, the cv- qualifiers (if any) on the function itself and the class in which
the member function is declared.2) The signature of a function template specialization includes the types of
its template arguments (14.5.5.1).


Добавлено через 1 минуту и 30 секунд
cv- qualifiers - это const volatile квалификаторы (если что smile )

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)