LINUX.ORG.RU

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

 


0

0
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

> И что? Ты не передашь массив в функцию.

> *икнул* а что же я делаю?


Передаешь указатель. Разницу ты так и не понял.

> потребовалось для подсчёта количества элементов сишного массива. sizeof(arr)/sizeof(elem) в таком случае не работает


Жжошь, сцуко!

LamerOk ★★★★★
()
Ответ на: комментарий от jtootf

>>Это фейл

>почему?

Я уже всю клавиатуру стоптал в плюсосрачах почему я не хочу видеть в .h ничего кроме незавершенных типов.

Absurd ★★★
()
Ответ на: комментарий от LamerOk

>Объявление массива выделяет под него память.

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

в противном случае (если размер надо в сигнатуре фиксировать) можно воспользоваться трюком, который я нарисовал чуть выше

jtootf ★★★★★
() автор топика
Ответ на: комментарий от jtootf

Что б ты не плакал от моей надоедливости, давай я похолопаю одной ладошкой. Это, правда, для детей, но вдруг тебя проймёт.

void f(const char *s1, const char s2[1024])
{
    int i = 0;
    char str[1024];
    str[i++] = *(s1+2);
    str[i++] = s1[2];
    str[i++] = *(s2+2);
    str[i++] = s2[2];
    str[i++] = '\0';
    printf("%s\n",str);
}


int main(int argc, char** argv)
{
    const char s1[] = "00000000";
    const char *s2 = "11111111";
    f(s1,s2);
    return 0;
}

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

>Передаешь указатель. Разницу ты так и не понял.

какой же ты всё-таки идиот :(

>Жжошь, сцуко!

предложи решение, отличное от моего. моё - работает; если твоё тоже будет работать, будешь иметь право его комментировать

jtootf ★★★★★
() автор топика
Ответ на: комментарий от LamerOk

>Это, правда, для детей

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

jtootf ★★★★★
() автор топика
Ответ на: комментарий от Absurd

>Я уже всю клавиатуру стоптал в плюсосрачах почему я не хочу видеть в .h ничего кроме незавершенных типов.

в моём примере всё находится в .cpp-файле; anyway, если ты хочешь падения в линк-тайм, то его сделать даже проще

jtootf ★★★★★
() автор топика
Ответ на: комментарий от lester

>и что люди только не делают, чтоб не пользоваться STL

ну вот ещё. меня как раз и интересует прежде всего STL, в свете его обобщённости на встроенные массивы

jtootf ★★★★★
() автор топика
Ответ на: комментарий от LamerOk

>Не буду оригинален

во-первых, это не твоё решение; во-вторых, это вообще не решение. решением для поставленной задачи будет boost.array, но никак не std::vector. тянуть boost мне накладно

jtootf ★★★★★
() автор топика
Ответ на: комментарий от jtootf

>print(a);

Правильно! Теперь компилим вот этот код(почти твой):

#include <iostream>

template <typename T, size_t n>
void print(T (&a)[n])
{
for(int i = 0; i < n; ++i)
{
std::cout << "a[" << i << "] = " << a[i] << std::endl;

a[2] = 999;
}
}

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

print (a);

std::cout << "a[2] = " << a[2] << std::endl;
}


и понимаем, что ктото слишком самоуверенно утверждал, что копирует массив в функцию, неправдали? ;)

golodranez ★★★★
()
Ответ на: комментарий от golodranez

>и понимаем, что ктото слишком самоуверенно утверждал, что копирует массив в функцию, неправдали? ;)

ну где я утверждал насчёт копирования? :) я утверждал тот факт, что тип, заявленный в сигнатуре, не совпадает с реальным типом. и требовал, чтобы компилятор надавал мне за это по рукам

jtootf ★★★★★
() автор топика
Ответ на: комментарий от jtootf

Твой "супер_способ_передачи_массива_в_функцию" это всеголишб:

void print(int *a)
{
for(int i = 0; i < 3; ++i)
{
std::cout << "a[" << i << "] = " << a[i] << std::endl;

a[2] = 999;
}
}

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

print (a);

std::cout << "a[2] = " << a[2] << std::endl;
}

не забываем, что для int a[3], a - это и есть указатель на первый элемент массива.

golodranez ★★★★
()
Ответ на: комментарий от golodranez

>Твой "супер_способ_передачи_массива_в_функцию" это всеголишб:

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

jtootf ★★★★★
() автор топика
Ответ на: комментарий от golodranez

>От нас не уйдёшь:))

передать != скопировать ;) передать можно и по указателю, и по ссылке

jtootf ★★★★★
() автор топика
Ответ на: комментарий от golodranez

>Да, дополнительным параметром. Я почемуто думал это стандартный способ:)

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

jtootf ★★★★★
() автор топика
Ответ на: комментарий от jtootf

>передать != скопировать ;)

ну не надо жонглоровать словами, я же умею читать:)

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

ммм... ты уверен, что знаешь чем они отличаются? рассказывай:)

golodranez ★★★★
()
Ответ на: комментарий от golodranez

>ммм... ты уверен, что знаешь чем они отличаются? рассказывай:)

указатели от ссылок? мутабельностью, наличием нуля, арифметикой

>ну не надо жонглоровать словами, я же умею читать:)

ну вас. но я таки нигде не имел в виду копирования, ибо для решения поставленной задачи это несущественно

jtootf ★★★★★
() автор топика
Ответ на: комментарий от golodranez

void f(const int[3]);

...

f({1, 2, 3});

вопрос был "почему ^так нельзя?" Ответ, который я тебе уже писал: потомучто нельзя передать массив в функцию. f(const int[3]) == f(const int*)

ЗЫ Честно, синтаксис вроде f(int[3]) увидел впервые в жизни и никак не мог понять чего ты хочешь добиться, объявляя функцию так.

golodranez ★★★★
()
Ответ на: комментарий от golodranez

>Так в чём вопросто изначальный был?

дано: статический массив размера n. задача: написать такую функцию f, чтобы при передаче в неё статического массива размера n всё компилировалось и работало, а при любом другом размере - происходила ошибка компиляции (или линковки, хотя мне такой вариант меньше нравится). т.е. статический массив должен сохранять свои статические свойства при передаче в функцию

jtootf ★★★★★
() автор топика
Ответ на: комментарий от jtootf

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

в С не совсем строгая типизация. в данном случае это удобно.

anonymous
()
Ответ на: комментарий от golodranez

>Ответ, который я тебе уже писал: потомучто нельзя передать массив в функцию. f(const int[3]) == f(const int*)

не, с этим уже разобрался. дело не в передаче массива (вернее, не напрямую), дело в том, как компилятор обрабатывает составные литералы, отличные от строк. если бы с массивом int'ов он работал так же, как сейчас работает со строками - проблемы бы не было

тем более что свежий g++ (при явном указании типа) с задачей вполне уже справляется

jtootf ★★★★★
() автор топика
Ответ на: комментарий от anonymous

>в С не совсем строгая типизация. в данном случае это удобно.

смотря для чего. к слову, в C в этом смысле всё как раз более-менее однородно (в C99 так вообще весьма мило), здесь же речь о С++ (текущем стандарте, не C++0x)

jtootf ★★★★★
() автор топика
Ответ на: комментарий от jtootf

>статические свойства при передаче в функцию

железо так не работает. С создан чтобы быть максимально близким к железу. плюсы создавались как расширение.

anonymous
()
Ответ на: комментарий от anonymous

>железо так не работает

это compile-time данные - времени семантического анализа, даже не кодогенерации. при чём тут железо?

jtootf ★★★★★
() автор топика
Ответ на: комментарий от jtootf

>это compile-time данные - времени семантического анализа, даже не кодогенерации. при чём тут железо?

ты уверен, что такая бесполезная функция в языке ничего не сломает в плане совместимости?

anonymous
()
Ответ на: комментарий от anonymous

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

бесполезная функция - наличие сигнатур вида R (T (&)[n]), которые на самом деле объявляют функцию вида R (T*). логично было бы либо от них избавиться вообще - либо сделать так, чтобы они работали

jtootf ★★★★★
() автор топика
Ответ на: комментарий от anonymous

>А прототип на что? Я уже это писал

который ты из анонимусов, и что именно ты писал?

jtootf ★★★★★
() автор топика
Ответ на: комментарий от anonymous

>ололо, а char a[]="KYSB", не работает?

работает, про него я и забыл. спасибо:)

golodranez ★★★★
()
Ответ на: комментарий от jtootf

>ты настоящий Ъ :)

Причём сообщение в конце треда он прочитал:)))

golodranez ★★★★
()
Ответ на: комментарий от golodranez

>>Так в чём вопросто изначальный был?

такой вопрос на 4-й странице - зачёт однозначно :)))

По теме - да, это не жабоскрипт :(

alex_custov ★★★★★
()

> {} - это, вроде бы, конструктор для const T[];

нет

struct S { int i; const char* s; };

S s1={1,"asdf"};

S s2={1,0};

int a[]={1,0};

я бы предположил, что {} - конструктор для... эээ... const Tuple<Anything,...>

ну и вообще не верю я в плюсовый синтаксис, плюсам нужна ресинтаксификация

www_linux_org_ru ★★★★★
()

Ждём треды [C++] зачем? [С++] что делать? [C++] кто виноват?

Больше плюсосрачей хороших и разных!

anonymous
()
Ответ на: комментарий от anonymous

Это даже не срачь, это какие-то коллективные тормоза, когда весь день десять человек пересказывают одни и те же вещи разными словами.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.