29.10.09

К.О. не всесилен

could not deduce template argument for 'char [N]' from 'char [64]' :(
И боюсь, что Капитан Очевидность на этот раз не придёт на помощь.

Ах если бы Холмс писал компиляторы..

7 комментариев:

  1. Да, увы и ах, но в ф-ии

    template (size_t N)void foo(char a[N]){}

    N никак не выведется из foo("aaa") :( даже из

    char s[] = "dsf";
    foo(s);

    не вывелется, увы. Да и зачем?

    ОтветитьУдалить
  2. Ну как зачем? Мало ли применений можно найти..
    Безопасные операции со строками без необходимости указывать размер целевого буфера - это только первое что в голову приходит) Без всяких там
    sprintf_s<_ARRAYSIZE(buf)>(buf, "..", ..)
    :)

    ОтветитьУдалить
  3. Таак. Это становится интересным.
    char buf[64];
    sprintf_s(buf, "%f", .1 );
    прекрасно компилится и работает.
    о_О, подумал я, пошёл взглянуть на прототип повнимательнее, и - ага! - ещё один секрет С++ для меня раскрыт: если аргумент сделать ссылкой на массив (char (&a)[N]), то N волшебным образом выводится.

    Должен сказать спасибо за твоё "Да и зачем?", без которого я не полез бы проверять sprintf_s. =)

    ОтветитьУдалить
  4. Хм, интересно-интересно. Вот как оно оказывается! Но самое неприятное здесь, что для каждого различного N будет инстанциироваться новая специализация, что при большом объеме ф-ии и большом кол-ве разных N может привести к нежелательному распуханию кода. Хотя бох его знает, может оптимизатор это и прожует, хотя надеяться не стоит. Посему, я все же считаю что лучше будет оперировать const char* (const wchar_t*), а для удобства это в шаблон обарачивать. Типа

    template(size_t N) void foo( char (&s)[N]){foo(s,N);}
    void foo(const char* s, size_t n) {...}

    Хоть это и решит проблему распухания кода, уж точно ясноти не внесет ))

    ОтветитьУдалить
  5. Ыгы)

    Ну кстати ясность - имхо, такая вещь, которой иногда бывает полезно пренебречь (хотя лишней она, конечно, никогда не бывает)). STL, boost - это же лютый пипец внутрях, зато снаружи - мягкие и пушистые. :) Да и хорошие доки не последнюю роль играют.

    ОтветитьУдалить
  6. Да, внутренности boost'а - это ваще полный коматоз. MPL и все что на нем основано - лютая и бешеная смерть. Например, очень интересно бывает используя Boost.Spirit смотреть на одну всего-лишь ошибку, сообщение о которой составляет всего-ничего 80кб текста очень сомнительной полезности. Вменяемые сообщения об ошибках в шаблонах - вот что действительно нужно С++.

    ОтветитьУдалить
  7. Знакомо, да))) Такого чтоб на 80 кило - не было, но таки напрягает.
    Кстати, фенькс за наводку на MPL. На днях как раз столкнулся с необходимостью в более-менее серьёзном юзе шаблонов (надо было сделать инициализацию толстого массива, уникального на каждый N шаблона функции, прозрачно для вызывающего; да-да, тот самый N, только там не строки =) ), с задачей справился без проблем, но интересно влезть в метапрограмминг поглубже.

    ОтветитьУдалить