Я бы сказал, что я разумного о них мнения, и предпочел бы не расчитывать лишний раз на них. Это стандартные Release настройки VS2K5SP1.
Более того, если бы Вы внимательно посмотрели на код, который сами же привели, то увидели бы, что копирование происходило, просто такой Вы подобрали пример, что скопировать надо 4 байта — 3 'a' и завершающий 0. Что как раз влезает в DWORD, который и скопировался.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
L>Только в первой строке произойдет копирование в буфер. Хотелось бы этого по возможности избежать. А во второй избежать вызова strlen или совсем, или хотя бы многократного.
L>Если есть 2 класса, один из которых, скажем ограничивает интерфейс только константными методами, а второй копирует в буфер только по необходимости, то совсем замечательно было бы.
void f (const char* ptr, int sz) {}
template<int N>
void f(const char (&arr)[N])
{
return f(arr, N-1);
}
int main()
{
f("Hello");
return 0;
}
Здравствуйте, LelicDsp, Вы писали:
L>>>Хм, как насчет того, что дублируются строки? А если они длинные? LD>Нефига они не дублируются, sizeof() вычисляется на этапе компиляции, это не вызов функции.
Два строковых литерала запросто могут дважды оказаться в бинарнике. От компилятора, в общем, зависит. У VC опцией рулится.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Есть ли какой-нибудь класс, служащий оберткой для строковых литералов.
Что-нибудь в духе
std::string s="Hello";
f(s.c_str(),s.size());
Только в первой строке произойдет копирование в буфер. Хотелось бы этого по возможности избежать. А во второй избежать вызова strlen или совсем, или хотя бы многократного.
Если есть 2 класса, один из которых, скажем ограничивает интерфейс только константными методами, а второй копирует в буфер только по необходимости, то совсем замечательно было бы.
L>Так это к каждой функции нужно писать обертку. Хотя явно лучше варианта MShura. А всё таки легковесного класса нет?
как вариант:
template<typename T, int len>
int str_len_ct(const T (&)[len])
{
return len-1;
}
int main(int argc, const char * argv[])
{
int len = str_len_ct("Hello");
int len2 = str_len_ct(L"unicode");
}
class constStr {
public:
template<int N>
constStr( const char (&str)[N] ) : ptr( str ), count( N ) {}
operator const char*() const { return ptr; };
int size() const { return count; }
// тут добавь интерфейса по вкусу...private:
char const * const ptr;
const int count;
};
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, lifrsdn, Вы писали:
L>Только в первой строке произойдет копирование в буфер. Хотелось бы этого по возможности избежать. А во второй избежать вызова strlen или совсем, или хотя бы многократного.
L>Если есть 2 класса, один из которых, скажем ограничивает интерфейс только константными методами, а второй копирует в буфер только по необходимости, то совсем замечательно было бы.
Может имеет смысл посмотреть в сторону const_string ?
[RSDN@Home 1.2.0 alpha rev. 775 on Windows XP 5.1.2600.131072]
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
L>И более-менее стандартного при этом нет?
Имхо нет, да и работать это будет только со статически константными строками, определенными в этом же модуле.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Bell, Вы писали: А>error C2784: 'size_t arr_size(const T [t_n])' : could not deduce template argument for 'const T [t_n]' from 'int [12]' А>(VS2005)
А>?
Потому, что f( T t[] ), f( T t[12] ) и f( T* const t ) эквивалентны. Так что вывести длину массива действительно никак не получится.
Хинт: как передавать массив по значению собираешься?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Compile-time strlen
От:
Аноним
Дата:
29.11.07 19:49
Оценка:
Здравствуйте, Erop, Вы писали:
E>Потому, что f( T t[] ), f( T t[12] ) и f( T* const t ) эквивалентны. Так что вывести длину массива действительно никак не получится. E>Хинт: как передавать массив по значению собираешься?
Во блин. Прикольный язык, ИМХО его невозможно выучить до конца — пока выучишь, новый стандарт приймут
Я знал, что f( T t[] ) эквивалентно f( T* const t ),
но как-то не подумал что f( T t[X] ) == f( T t[Y] ) == f( T t[] ) == f( T* const t ).
Спасибо.
L>Только в первой строке произойдет копирование в буфер. Хотелось бы этого по возможности избежать. А во второй избежать вызова strlen или совсем, или хотя бы многократного.
L>Если есть 2 класса, один из которых, скажем ограничивает интерфейс только константными методами, а второй копирует в буфер только по необходимости, то совсем замечательно было бы.
Насчет копирование решается просто: Boost.Range (Поиск по форуму помогает )
Здравствуйте, lifrsdn, Вы писали:
L>Здравствуйте, _nn_, Вы писали:
__>>Насчет копирование решается просто: Boost.Range (Поиск по форуму помогает )
__>>
Здравствуйте, Аноним, Вы писали:
А>Во блин. Прикольный язык, ИМХО его невозможно выучить до конца — пока выучишь, новый стандарт приймут
За похвалу конечно спасибо, но это всё-таки заблуждение. ИМХО можно довольно глубоко
Ну да это просто комитет нас щадит
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Написать-то можно, но как известно, всё украдено до нас. Может кто уже сделал такое.
Ну ct-strlen можно много как написать. Только объект иметь таки удобнее. Его же копировать там можно, begin end приделать и всё такое...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, np9mi7, Вы писали:
N>Здравствуйте, lifrsdn, Вы писали:
L>>Только в первой строке произойдет копирование в буфер. Хотелось бы этого по возможности избежать. А во второй избежать вызова strlen или совсем, или хотя бы многократного.
L>>Если есть 2 класса, один из которых, скажем ограничивает интерфейс только константными методами, а второй копирует в буфер только по необходимости, то совсем замечательно было бы.
N>Может имеет смысл посмотреть в сторону const_string ?
Спасибо большое, скачал, разбираюсь. Буду профилировать с этими строками.
Написать-то можно, но как известно, всё украдено до нас. Может кто уже сделал такое.
E>Ну ct-strlen можно много как написать. Только объект иметь таки удобнее. Его же копировать там можно, begin end приделать и всё такое...
Так никто не спорит, тем более не сильно и отличаются Ваш class constStr от моего template<typename T, int len> class StringLiteral.
Здравствуйте, lifrsdn, Вы писали:
L>Так никто не спорит, тем более не сильно и отличаются Ваш class constStr от моего template<typename T, int len> class StringLiteral.
Принципиально отличается. У меня тип объекта не зависит от его значения...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, lifrsdn, Вы писали:
L>>Так никто не спорит, тем более не сильно и отличаются Ваш class constStr от моего template<typename T, int len> class StringLiteral.
E>Принципиально отличается. У меня тип объекта не зависит от его значения...
Здравствуйте, lifrsdn, Вы писали:
L>Более того, если бы Вы внимательно посмотрели на код, который сами же привели, то увидели бы, что копирование происходило, просто такой Вы подобрали пример, что скопировать надо 4 байта — 3 'a' и завершающий 0. Что как раз влезает в DWORD, который и скопировался.
Решение которое, надеюсь, вас устроит в ветке уже предложили.
Можно вариацию вроде:
__>>Вы плохого мнения о компиляторах. __>>Компилятор умеет оптимизировать эту вещь и не делать настоящего копирования.
... L>Я бы сказал, что я разумного о них мнения, и предпочел бы не расчитывать лишний раз на них. Это стандартные Release настройки VS2K5SP1.
...
Чтобы помочь компилятору в его сложной работе достаточно сделать выражение const char a[] = "aaa"; глобальным.
Никаких дополнительных расходов, один недостаток — область видимости вся единица трансляции.
Здравствуйте, _nn_, Вы писали:
__>Здравствуйте, lifrsdn, Вы писали:
L>>Более того, если бы Вы внимательно посмотрели на код, который сами же привели, то увидели бы, что копирование происходило, просто такой Вы подобрали пример, что скопировать надо 4 байта — 3 'a' и завершающий 0. Что как раз влезает в DWORD, который и скопировался.
__>Решение которое, надеюсь, вас устроит в ветке уже предложили.
Предложили даже 2 решения, сейчас занимался проверкой, что лучше по скорости. Проблема в том, что в некотором legacy коде, производительности которого не хватает на имеющемся железе буквально чуть-чуть, во внутренних циклах порядочно вызовов strlen от строковых литералов. Естественно, что появилась мысль их убрать за ненадобностью. Искался самый простой вариант.
Здравствуйте, MShura, Вы писали:
MS>Чтобы помочь компилятору в его сложной работе достаточно сделать выражение const char a[] = "aaa"; глобальным. MS>Никаких дополнительных расходов, один недостаток — область видимости вся единица трансляции.
Не то, чтобы это сильно мешало. В конце-концов, если пересекутся 2 одинаковых объекта, построенных на одинаковых строковых литералах, то можно оставить любой из них, но не вижу смысла так глобально модифицировать код, да и для использования make_iterator_range необходимо, как минимум, написать заглушки к каждой используемой функции.
L>>Хм, как насчет того, что дублируются строки? А если они длинные?
Нефига они не дублируются, sizeof() вычисляется на этапе компиляции, это не вызов функции.
MS>#define STR_HELLO "Hello"
После обработки препроцессором это даст тотже самый sizeof("Hello")
Здравствуйте, LelicDsp, Вы писали:
L>>>Хм, как насчет того, что дублируются строки? А если они длинные? LD>Нефига они не дублируются, sizeof() вычисляется на этапе компиляции, это не вызов функции.
Строки дублируются в исходном коде. Что иногда приводит к неприятным ошибкам.
Здравствуйте, Sergey, Вы писали:
S>Здравствуйте, LelicDsp, Вы писали:
L>>>>Хм, как насчет того, что дублируются строки? А если они длинные? LD>>Нефига они не дублируются, sizeof() вычисляется на этапе компиляции, это не вызов функции.
S>Два строковых литерала запросто могут дважды оказаться в бинарнике. От компилятора, в общем, зависит. У VC опцией рулится.
Кстати, а зачем интересно могут понадобится 2 одинаковые строки в бинарнике? Ну, что проще спихать туда все, не сортируя, это понятно.
Здравствуйте, lifrsdn, Вы писали:
L>Кстати, а зачем интересно могут понадобится 2 одинаковые строки в бинарнике? Ну, что проще спихать туда все, не сортируя, это понятно.
Тяжкое наследие С
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
L>>>Хм, как насчет того, что дублируются строки? А если они длинные? LD>Нефига они не дублируются, sizeof() вычисляется на этапе компиляции, это не вызов функции.
MS>>#define STR_HELLO "Hello" LD>После обработки препроцессором это даст тотже самый sizeof("Hello")
Приведенное решение упрощало работу с длинными запись
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, lifrsdn, Вы писали:
L>>Кстати, а зачем интересно могут понадобится 2 одинаковые строки в бинарнике? Ну, что проще спихать туда все, не сортируя, это понятно.
E>Тяжкое наследие С
Здравствуйте, lifrsdn, Вы писали:
L>А поподробней в этом месте, пожалуйста.
Ну когда-то можно было полазать грязными лапами внутри литерала...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, LelicDsp, Вы писали:
L>>>Хм, как насчет того, что дублируются строки? А если они длинные? LD>Нефига они не дублируются, sizeof() вычисляется на этапе компиляции, это не вызов функции.
Вы о чем? Кто с этим спорит?
MS>>#define STR_HELLO "Hello" LD>После обработки препроцессором это даст тотже самый sizeof("Hello")
Что Вы хотели этим сказать и к чему?
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth