Linux.org.ru
Новости - Галерея - Форум - Трекер - Wiki - Поиск
[#]  
jtootf (фотография)

[C++] почему?

void f(const int[3]); 
 
... 
 
f({1, 2, 3});

почему так нельзя? при том, что вот так:

const int a[3] = {1, 2, 3}; 
 
f(a);

вполне себе законно. {} - это, вроде бы, конструктор для const T[]; конструкторы в вызове функции использовать вполне себе можно. основание для такого особого отношения есть вообще?

это всё при том, что:

void g(const char[3]); 
 
... 
 
g("123");

замечательно работает. C-style строка в C++ - она, в общем-то, массив символов - два исключения из общих языковых правил в одном выражении

ну и то, что и в f и в g можно с лёгкостью передавать массивы большего размера, чем указано в сигнатуре, тоже как-то нехорошо. приведение T[] к T* это, конечно, не так уж и плохо - но толку тогда от такой сигнатуры, спрашивается, если компилятор (с -Wall -pedantic) даже предупреждения не выдаёт?

jtootf ** (27.10.2009 2:37:50)

[#] Ответ на: Re: [C++] почему? от anonymous 28.10.2009 0:20:37  
golodranez (фотография)

[C++] почему?

Ура, анонимусы постепенно подтягиваются :)

golodranez *** (28.10.2009 0:24:43)
[#] Ответ на: Re: [C++] почему? от LamerOk 27.10.2009 18:37:12  

[C++] почему?

>Чего ж тут непонятного? Ты видишь здесь объявление массива?

Не так быстро.... Первоначально речь шла о переменной и о выражении. Теперь ты говоришь об объявлении массива. Что ты подразумеваешь под "объявлением"? Инициализацию (в примере - локальная переменная)? Но я всегда думал, что объявление типа переменной и её инициализацию можно "разнести" (ошибаюсь?).

Ладно, можешь не отвечать: выше уже всё разъяснили...

P.S. Хочешь узнать правду о С++? Не лезь в срач "С++ vs. весь остальной мир" - лезь в "плюсосрач" :):):)

yyk *** (28.10.2009 9:27:36)
[#] Ответ на: [C++] почему? от yyk 28.10.2009 9:27:36  

Re: [C++] почему?

> Что ты подразумеваешь под "объявлением"? Инициализацию (в примере - локальная переменная)?

Как можно перепутать покупку автомобиля с ездой на нем?

> объявление типа переменной и её инициализацию можно "разнести" (ошибаюсь?).


Разумеется можно. Это никак не связанные друг с другом операции.


> Первоначально речь шла о переменной и о выражении.


Она весь тред об этом шла. Я пытался указать на общеизвестный факт - оператор [] в выражении и оператор [] в объявлении переменной имеют разную семантику.

LamerOk ** (28.10.2009 19:35:24)
[#] Ответ на: Re: [C++] почему? от LamerOk 28.10.2009 19:35:24  

[C++] почему?

>Она весь тред об этом шла. Я пытался указать на общеизвестный факт - оператор [] в выражении и оператор [] в объявлении переменной имеют разную семантику.

Аааа, ты опять об этом:

>Тип char[] идентичен типу char* Это разная запись одной и той же семантической конструкции.


Т.е. у одной "семантической конструкции" есть несколько вариантов записей, а одна и та-же "запись" в зависимости от контекста обозначает разные "семантические конструкции"?

И эти люди запрещают мне ковыряться в носу... =)

yyk *** (28.10.2009 21:15:29)
[#] Ответ на: [C++] почему? от yyk 28.10.2009 21:15:29  

Re: [C++] почему?

Бинго.

LamerOk ** (28.10.2009 21:51:52)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 2:53:08  

Re: [C++] почему?

>правильный вопрос - почему этого нельзя?

Потому что неизвестен тип элементов массива. Это может быть char, int, float - что угодно. Одних фигурных скобочек недостаточно.

Но можно так:

[legolegs@battlehummer ~]$ g++ -x c++ -Wall -Wextra -O - -std=c++0x  && ./a.out 
#include <iostream> 
using namespace std; 
typedef int AR[2][2]; 
int f(AR arg) 
{ 
return arg[0][0]; 
} 
int main() 
{ 
cout << f(AR{ { 1,2 }, {3,4 } }) << endl; 
} 
1 

legolegs * (29.10.2009 17:41:10)
[#] Ответ на: Re: [C++] почему? от legolegs 29.10.2009 17:41:10  
jtootf (фотография)

[C++] почему?

>Потому что неизвестен тип элементов массива. Это может быть char, int, float - что угодно. Одних фигурных скобочек недостаточно.

мне так и не ответили - чем это отличается от одиночного численного литерала? 1 имеет тип char, int, float?

jtootf ** (29.10.2009 17:55:25)
[#] Ответ на: [C++] почему? от jtootf 29.10.2009 17:55:25  

Re: [C++] почему?

#include <iostream> 
using namespace std; 
typedef int arr3[3]; 
struct struct3 
{ 
  int a1; 
  double a2; 
  char a3; 
}; 
struct struct4 
{ 
  int a1; 
  double a2; 
  char a3; 
  void *a4; 
}; 
 
struct A 
{ 
  void m(arr3 arg) {cout << "arr3\n"; } 
  void m(struct3 arg) {cout << "struct3\n"; } 
  void m(struct4 arg) {cout << "struct4\n"; } 
}; 
 
int main() 
{ 
  A a; 
  arr3 b = {1,2,3}; 
  struct3 c = {1,2,3}; 
  a.m( b ); 
  a.m( c ); 
  a.m( {1,2,3} ); //что вызвать? 
}

legolegs * (29.10.2009 18:13:39)
[#] Ответ на: Re: [C++] почему? от legolegs 29.10.2009 18:13:39  
jtootf (фотография)

[C++] почему?

>a.m( {1,2,3} ); //что вызвать?

это проблема не с типами элементов массива, а с тем, что один и тот же compound literal описывает и гомогенный массив, и гетерогенный кортеж. в противном случае тип массива определялся бы в точности так же, как и тип несоставного численного литерала (либо, что ближе, как тип арифметического выражения с чиленными литералами) - т.е. {1.0, 2, 3}, например, имеет тип double[3]

jtootf ** (29.10.2009 19:02:13)
[#] Ответ на: [C++] почему? от jtootf 29.10.2009 17:55:25  
alex_custov (фотография)

[C++] почему?

наверно разработчики языка на то время даже не думали, что такое может понадобится.

alex_custov *** (29.10.2009 20:24:00)
[#] Ответ на: Re: [C++] почему? от legolegs 29.10.2009 17:41:10  
alex_custov (фотография)

[C++] почему?

>>Потому что неизвестен тип элементов массива.

здрасте, целочисленные литералы без модификаторов - числа int. Тип входного значения в функции у jtootf абсолютно точно известен, автоматический кастинг тоже имеется если понадобится (int -> double, например). Теперь действительно возникает вопрос почему это нельзя. Ответ мне кажется я написал выше, видимо об этом тогда ещё не думали, зато подумали в c++0x. Точно такой же вопрос можно задать по поводу VLA.

alex_custov *** (29.10.2009 20:29:42)
[#] Ответ на: [C++] почему? от alex_custov 29.10.2009 20:29:42  
jtootf (фотография)

[C++] почему?

>автоматический кастинг тоже имеется если понадобится (int -> double, например)

кастинг тут работать не будет - т.к. compound literal для массива есть по сути указатель на сегмент данных, а размеры int и double различны (арифметика поломается). однако при совпадении типов (или хотя бы размеров) всё должно работать без проблем

jtootf ** (29.10.2009 21:04:15)

http://www.linux.org.ru/

Rambler's Top100 TopList