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)

[#]  
alex4 (фотография)

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

Вот так. Это тебе не лисп.

alex4 (27.10.2009 2:46:28)
[#]  
alex4 (фотография)

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

Зачем кстати это надо? Лень лишние переменные заводить под аргументы функции? Можно сделать что-нибудь вроде

 
{ 
int temp_array[3] = {var1, var2, var3}; 
func(temp_array); 
} 

alex4 (27.10.2009 2:49:48)
[#] Ответ на: [C++] почему? от alex4 27.10.2009 2:49:48  
jtootf (фотография)

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

>Зачем кстати это надо?

это неправильный вопрос. правильный вопрос - почему этого нельзя? меня не очень интересует практическая сторона, меня интересуют соображения, по которым этой возможности в C++ нет

>Можно сделать что-нибудь вроде

можно. я даже в исходном сообщении потрудился об этом написать

jtootf ** (27.10.2009 2:53:08)
[#] Ответ на: [C++] почему? от alex4 27.10.2009 2:49:48  
jtootf (фотография)

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

да, и ещё пусть мне кто-нибудь расскажет, почему вот так тоже нельзя:

const int a[2][2] = {{1, 2}, {3, 4}};

при том, что вот так можно:

const int a[2][3] = {{0}};

jtootf ** (27.10.2009 3:00:47)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 3:00:47  
jtootf (фотография)

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

const int a[2][2] = {{0}};

fix

jtootf ** (27.10.2009 3:01:55)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 3:00:47  
alex4 (фотография)

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

нет

alex4 (27.10.2009 3:32:54)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 3:00:47  
alex4 (фотография)

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

а что за компилятор такой?

alex4 (27.10.2009 3:33:59)
[#] Ответ на: [C++] почему? от alex4 27.10.2009 3:32:54  
jtootf (фотография)

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

>нет

нет что?

>а что за компилятор такой?

g++ (GCC) 4.2.3 (Gentoo 4.2.3 p1.0)

jtootf ** (27.10.2009 3:35:35)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 2:53:08  
alex4 (фотография)

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

Цитата

почему этого нельзя?

Потому, что массив нельзя использовать как литерал вне формы инициализации, как и любой другой не примитивный тип (по крайней мере в языке C). Так ведь понятнее?

alex4 (27.10.2009 3:38:24)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 3:35:35  
alex4 (фотография)

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

А что он пишет, если попытаться скомпилировать этот пример?

alex4 (27.10.2009 3:39:12)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 3:35:35  
alex4 (фотография)

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

У меня gcc 4.3.2 и все нормально работает. В языке C AFAIK стандарт это можно. В C++ вроде бы то же самое.

alex4 (27.10.2009 3:41:04)
[#] Ответ на: [C++] почему? от alex4 27.10.2009 3:38:24  
jtootf (фотография)

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

>Потому, что массив нельзя использовать как литерал вне формы инициализации, как и любой другой не примитивный тип

чем строка "123" существенно отличается от массива char a[3] = {'1', '2', '3'}? иными словами, ответа я не вижу - да, нельзя. а почему нельзя?

jtootf ** (27.10.2009 3:45:49)
[#] Ответ на: [C++] почему? от alex4 27.10.2009 3:41:04  
jtootf (фотография)

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

>все нормально работает

таки работает. ладно, этот вопрос снимается :)

jtootf ** (27.10.2009 3:47:08)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 3:45:49  
alex4 (фотография)

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

"123" это значение простого типа, а {'1', '2', '3'} составного. Больше никакой разницы нет. Очевидно или сложилось исторически или для читаемости. Что такое принимает f в

f("124", 4, "12")

понятно, а в

f({"124", {4, "12"}})

не очень.

alex4 (27.10.2009 3:51:44)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 3:45:49  
alex4 (фотография)

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

Вообще в последнем стандарте C такая штука есть. В C++ врядли.

alex4 (27.10.2009 3:54:53)
[#] Ответ на: [C++] почему? от alex4 27.10.2009 3:51:44  
jtootf (фотография)

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

>"123" это значение простого типа, а {'1', '2', '3'} составного

можно уточнить типы? я разницы по-прежнему не вижу

>не очень

ну ясное дело, у тебя там ill-formed массив - {4, "12"} быть не может, ибо у 4 и "12" типы как раз разные

jtootf ** (27.10.2009 3:57:21)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 3:57:21  
alex4 (фотография)

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

Цитата

можно уточнить типы? я разницы по-прежнему не вижу

Массив может содержать в себе другие массивы, а строка нет. Определение(bnf) составного типа рекурсивно.

Цитата

ill-formed массив

Точно. Я о структурах думал.

alex4 (27.10.2009 4:01:11)
[#] Ответ на: [C++] почему? от alex4 27.10.2009 4:01:11  
jtootf (фотография)

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

>Массив может содержать в себе другие массивы, а строка нет. Определение(bnf) составного типа рекурсивно.

грамматическое определение, опять же, неинтересно. семантически, строка - это char[]; строковый литерал имеет тип const char[] соответствующей размерности. разницы на уровне _типов_ - нет. если есть возражения, прошу (повторно) объявить типы для строки и для массива char'ов, чтобы можно было их сравнить

>строка нет

собственно, ответа это всё равно не даёт. да, массив обладает свойством замыкания,- и как это препятствует такому вот его созданию?

складывается впечатление, что грамматика C++ местами не дружит с его же семантикой

jtootf ** (27.10.2009 4:07:01)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 4:07:01  
alex4 (фотография)

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

Очевидно, что дело именно в синтаксисе. В С99 такое есть.

alex4 (27.10.2009 4:50:48)
[#] Ответ на: [C++] почему? от alex4 27.10.2009 4:50:48  
alex4 (фотография)

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

Собственно к этому и первый комментарий.

alex4 (27.10.2009 4:51:19)
[#]  
beastie (фотография)

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

да можно

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

beastie ** (27.10.2009 6:32:53)
[#] Ответ на: [C++] почему? от beastie 27.10.2009 6:32:53  

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

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

Это вообще звиздец какой-то.

Miguel ** (27.10.2009 8:05:19)
[#] Ответ на: [C++] почему? от alex4 27.10.2009 4:51:19  

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

А можно так?

 
template <typename T> 
void fn(T const &t) 
{ 
  // do something with t 
} 
 
enum { 
  kInt, 
  kString 
} type = kString; 
 
fn( type == kString ? "привет, начинки для гробов" 
  : type == kInt    ? 123 
  : assert("в type-e говно какое-то", false)); 

Короче говоря, реализовать алгебраические типы.

l5k (27.10.2009 9:45:22)
[#]  

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

> void f(const int[3]);

> ...

> f({1, 2, 3});

> почему так нельзя?

1, 2, 3 - они какого типа? short, int? unsigned?

tailgunner **** (27.10.2009 10:11:11)
[#]  
Loronymous (фотография)

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

Цитата

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

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

Нет там никакого конструктора. {} - это инициализатор массива, используется только для инициализации.

Цитата

при том, что вот так: const int a[3] = {1, 2, 3}; f(a); вполне себе законно

Законно, да.

Цитата

это всё при том, что: void g(const char[3]); g("123");

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

"123" - строковый литерал, const char[n+1]. Неявно приводится к char*.

Цитата

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

Массивы в функцию передаются только по указателю со всеми последствиями.

Может стоит литературу почитать?

Loronymous (27.10.2009 10:12:16)
[#]  

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

то чем аффтар возмущается , для меня довольно естественно
видимо , потому , что я лиспа не знаю

kto_tama ***** (27.10.2009 10:27:47)
[#] Ответ на: [C++] почему? от kto_tama 27.10.2009 10:27:47  

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

> видимо , потому , что я лиспа не знаю

Хаскеля же.

tailgunner **** (27.10.2009 10:30:54)
[#] Ответ на: [C++] почему? от tailgunner 27.10.2009 10:11:11  
balodja (фотография)

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

> 1, 2, 3 - они какого типа? short, int? unsigned?

А если еще и union забабахать? Тогда совсем "у-у-у".

balodja ** (27.10.2009 11:06:17)
[#] Ответ на: [C++] почему? от kto_tama 27.10.2009 10:27:47  
Love5an (фотография)

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

а при чем тут?

Возмущения автора как раз таки только к статически-типизированным языкам применимы. И в данном случае - в сравнении с хаскелем.

Love5an (27.10.2009 11:33:41)
[#] Ответ на: [C++] почему? от tailgunner 27.10.2009 10:11:11  
alex4 (фотография)

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

const int

alex4 (27.10.2009 11:34:16)
[#] Ответ на: [C++] почему? от Loronymous 27.10.2009 10:12:16  
alex4 (фотография)

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

Да, нет. Массивы можно ведь создавать на стеке и передавать по указателю.

alex4 (27.10.2009 11:36:04)
[#] Ответ на: [C++] почему? от Loronymous 27.10.2009 10:12:16  
jtootf (фотография)

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

>Массивы в функцию передаются только по указателю со всеми последствиями.

может, поспорим?

jtootf ** (27.10.2009 13:09:08)
[#] Ответ на: [C++] почему? от Loronymous 27.10.2009 10:12:16  
jtootf (фотография)

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

Цитата

{} - это инициализатор массива, используется только для инициализации

ок. объясни мне, будь добр, чем инициализатор отличается от конструктора

template <typename T> 
T h() 
{ 
    T obj(); 
 
    return obj; 
}

и что используется в данном случае

jtootf ** (27.10.2009 13:12:46)
[#] Ответ на: [C++] почему? от tailgunner 27.10.2009 10:11:11  
jtootf (фотография)

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

>1, 2, 3 - они какого типа? short, int? unsigned?

о правилах приведения типов для числовых литералов в стандарте написано вполне себе ясно. вызвать функцию типа int как f(1) вполне себе можно, так почему же нельзя функцию типа int[2] вызвать как f({1, 2})?

если бы проблема была в этом, она была бы чуть более заметна - не находишь? к тому же сообщение об ошибке компиляции не имеет никакого отношения к типам

jtootf ** (27.10.2009 13:15:38)
[#] Ответ на: [C++] почему? от Love5an 27.10.2009 11:33:41  
jtootf (фотография)

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

>И в данном случае - в сравнении с хаскелем.

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

jtootf ** (27.10.2009 13:18:08)
[#] Ответ на: [C++] почему? от beastie 27.10.2009 6:32:53  
jtootf (фотография)

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

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

error: ISO C++ forbids compound-literals

jtootf ** (27.10.2009 13:21:01)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 13:18:08  
golodranez (фотография)

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

>неоднородность языка, на котором я в данный момент пишу.

Тебе уже объяснили, что конструкция которую ты хочешь использовать применяется ТОЛЬКО при инициализации массива, а "some_text" - это строковой литерал. Так что там про неоднородность?

golodranez *** (27.10.2009 13:50:53)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 13:15:38  
golodranez (фотография)

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

>так почему же нельзя функцию типа int[2] вызвать как f({1, 2})?

Ты должен передать в функцию указатель на массив. Где он? {1, 2} - не очень похоже на указатель.

golodranez *** (27.10.2009 13:53:52)
[#] Ответ на: [C++] почему? от golodranez 27.10.2009 13:50:53  
jtootf (фотография)

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

>конструкция которую ты хочешь использовать применяется ТОЛЬКО при инициализации массива

вот я и хочу узнать - почему. на этот вопрос никто так и не ответил

>Так что там про неоднородность?

интересно, а если в стандарте будет принято писать объявления перменных исключительно таким int a = tin(3) образом - что, все хором тоже дружно скажем "так надо"?

jtootf ** (27.10.2009 13:56:13)
[#] Ответ на: [C++] почему? от golodranez 27.10.2009 13:53:52  
jtootf (фотография)

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

>Ты должен передать в функцию указатель на массив

ок, не вопрос

>{1, 2} - не очень похоже на указатель.

"12" - похоже, а {1, 2} - не похоже? вся информация для выполнения такого действия у компилятора есть, в чём проблема?

jtootf ** (27.10.2009 13:57:48)
[#] Ответ на: [C++] почему? от golodranez 27.10.2009 13:53:52  
jtootf (фотография)

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

собственно, вопрос можно сократить - почему C++ forbids compound-literals? и почему сообщение о подобной ошибке можно получить, только явно прописав тип этого самого литерала (в противном случае сообщение есть только о синтаксической ошибке)?

jtootf ** (27.10.2009 13:59:56)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 13:15:38  

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

>> 1, 2, 3 - они какого типа? short, int? unsigned?

> о правилах приведения типов для числовых литералов в стандарте написано вполне себе ясно

Но тут числовые литералы надо привести к типу массива.

> если бы проблема была в этом, она была бы чуть более заметна - не находишь?

Я думаю, из-за этого (невозможности четко определить правила преобразования compound-дитерала) в стандарте и нет такого преобразования.

tailgunner **** (27.10.2009 14:00:47)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 13:56:13  

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

Очевидно же, крестофилия и ебланство - одинаковые по сути вещи.

l5k (27.10.2009 14:01:06)
[#] Ответ на: [C++] почему? от tailgunner 27.10.2009 14:00:47  
jtootf (фотография)

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

>Но тут числовые литералы надо привести к типу массива.

ну вот ещё. числовые литералы нужно привести к числу. к int, например (по стандарту именно так компилятор в данном случае и должен поступить); а затем уже можно разобрать compound literal, проверить чтобы все типы совпадали и привести к const int[literal_size]

>невозможности четко определить правила преобразования compound-дитерала

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

jtootf ** (27.10.2009 14:06:48)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 13:12:46  

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

> объясни мне, будь добр, чем инициализатор отличается от конструктора

Вот с этого и надо начинать.

LamerOk ** (27.10.2009 14:11:34)
[#] Ответ на: Re: [C++] почему? от LamerOk 27.10.2009 14:11:34  
jtootf (фотография)

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

>Вот с этого и надо начинать.

да нет, не столь это существенно на самом деле. достаточно трактовать инициализатор как составной литерал

jtootf ** (27.10.2009 14:14:09)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 13:57:48  

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

> "12" - похоже, а {1, 2} - не похоже? вся информация для выполнения такого действия у компилятора есть, в чём проблема?

Какого "такого"? Какое действие должен выполнить компилятор, встретив литерал {1,2}?

LamerOk ** (27.10.2009 14:15:20)
[#] Ответ на: Re: [C++] почему? от LamerOk 27.10.2009 14:15:20  
jtootf (фотография)

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

>Какое действие должен выполнить компилятор, встретив литерал {1,2}?

такое же, как и при встрече "12", с той лишь разницей, что в данном случае у нас массив не char[], а int[]

jtootf ** (27.10.2009 14:16:19)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 13:57:48  
golodranez (фотография)

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

>"12" - похоже, а {1, 2} - не похоже?

Пока да, но уже сейчас инициализация вроде "char *str = "asdf";" - deprecated.

golodranez *** (27.10.2009 14:16:25)
[#] Ответ на: [C++] почему? от jtootf 27.10.2009 14:14:09  

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

> достаточно трактовать инициализатор как составной литерал

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

LamerOk ** (27.10.2009 14:16:57)

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

Rambler's Top100 TopList