Здравствуйте, korzhik, Вы писали:
V>>Я так понял неявное приведение вызывается раньше чем инстанцирование шаблона, так? V>>Это правильно? K>Да не, просто не шаблонная функция имеет преимущество перед шаблонной
Так в данном случае, шаблонная функция, как мне кажется, является более специализированной для массива или нет?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Разные конечно. И кстати, насчёт моего предыдущего поста: я был не прав. Мой пример не аналогичен твоему примеру, т.к. в твоём случае передаётся сслыка на массив char из N элементов, а не ссылка на указатель на char
Здравствуйте, Vain, Вы писали: V>Вот, меня интересует почему это не компилируется.
Почему? Компилируется. Правда, если передавать в test массив char из 10-ти элементов, то возникает неоднозначная ситуация при выборе функции, о чём компилятор и сообщает. Во всех других случаях вызывается char* test(char *str)
Здравствуйте, ArtDenis, Вы писали:
AD>Почему? Компилируется.
Я не про общий случай спрашиваю AD>Правда, если передавать в test массив char из 10-ти элементов, то возникает неоднозначная ситуация при выборе функции, о чём компилятор и сообщает.
Вот, почему не компилируется. Я не спрашиваю про техническую сторону, она понятна, почему такое вообще не разрешено, каковы причины? Может есть какой пример, который может показать почему должна происходить неоднозначность? AD>Во всех других случаях вызывается char* test(char *str)
Про эти случаи мне и не интересно
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Вот, почему не компилируется. Я не спрашиваю про техническую сторону, она понятна, почему такое вообще не разрешено, каковы причины? Может есть какой пример, который может показать почему должна происходить неоднозначность?
Неоднозначность происходит в том случае, когда компилятор не знает, вызов какой функции надо подставить, т.к. аргуметы одинаково хорошо подходят для нескольких перегруженных функций:
void test(char (&str)[10]) {}
void test(char *str) {}
char arr[10];
test(arr); // Здесь одинаково хорошо можно подходит char *str и char (&)[10],
// т.к. массив может передаваться как по указателю, так и по сылке на свой тип
Но в твоём первом примере неоднозначности не происходит, т.к. как тебе уже ответили нешаблонная ф-ция имеет приоритет перед шаблонной.
Здравствуйте, ArtDenis, Вы писали:
AD>Неоднозначность происходит в том случае,
Опять, я не спрашиваю почему происходит неоднозначность, я спрашиваю почему она должна происходить, улавливаешь разницу? AD>Чтобы разрулить твою ситуацию можно сделать так:
AD>
V>Я так понял неявное приведение вызывается раньше чем инстанцирование шаблона, так?
На первый взгляд кажется, что шаблон, принимающий массив по ссылке, имеет преимущество, т.к. тут очевидный Exact Match,а для второй функции не все так очевидно.
Смотрим 4.2/2
A string literal (2.13.4) that is not a wide string literal can be converted
to an rvalue of type pointer to char;
...
For the purpose of ranking in overload resolution (13.3.3.1.1),
this conversion is considered an array-to-pointer conversion
followed by a qualification conversion (4.4).
Смотрим 13.3.3.1.1/3, таблицу 9. Там написано, что Array-to-pointer conversion и qualification conversion суть Exact Match, и
и поэтому получается, что вариант test(char *str) — тоже Exact Match, а значит имеет преимущество перед шаблоном.
Для иллюстрации можно привести такой пример:
namespace A {
char* test(char (&str)[1]) {
return 0;
}
char* test(char *str) {
return 0;
}
}
int main() {
char arr[] = "";
int arr[sizeof(A::test(arr))];
return 0;
};
В данном случае имеет место быть неоднозначность.
Обсуждение этой проблемы можно посмотреть также здесь
Здравствуйте, Bell, Вы писали:
B>Смотрим 13.3.3.1.1/3, таблицу 9. Там написано, что Array-to-pointer conversion и qualification conversion суть Exact Match, и
Вот мне кажется что Array-to-pointer должен быть неявным преобразованием, вам не кажется? B>и поэтому получается, что вариант test(char *str) — тоже Exact Match, а значит имеет преимущество перед шаблоном.
Перед шаблоном — да, а перед обычной функций по логике вещей должна быть нормальная перегрузка, а её нет, это то и недочёт.
B>Для иллюстрации можно привести такой пример: B>
V>Опять, я не спрашиваю почему происходит неоднозначность, я спрашиваю почему она должна происходить, улавливаешь разницу?
Так как в противном случае нарушалась бы семантика вызова в зависимости от контекста.
Имеем
void test(const char(&)[5]) // (1)
{
// do something
}
void test(const char*) // (2)
{
// do something different
}
Допустим, что обе функции не равнозначны с точки зрения перегрузки для массива из 5 элементов, т.е. первая предпочтительнее т.к. не требует array-to-pointer conversion.
test("test"); // "test" - это array of 5 const char, вызывается (1).const char* name = "test";
test(name); // name - это pointer to const char, вызывается (2).
СА>test("test"); // "test" - это array of 5 const char, вызывается (1).
СА>const char* name = "test";
СА>test(name); // name - это pointer to const char, вызывается (2).
СА>
СА>Получаем опасную неоднозначность вызова.
почему опасную?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]