Есть такой конструктор string(const char *, const char *), можно его как-то забиндить, чтобы не писать обертку RangeToString.
bind(&obj_class::method, ref(obj), bind(RangeToString(), _1, _2))
class RangeToString
{
public:
typedef string result_type;
string operator()(const char *first, const char *last) const
{
return string(first, last);
}
};
Спасибо.
Здравствуйте, Ароан, Вы писали:
А>Есть такой конструктор string(const char *, const char *), можно его как-то забиндить, чтобы не писать обертку RangeToString.
Нет нельзя. Т.к. ты уже используешь буст вместо написания велосипеда можешь использовать
http://www.boost.org/boost/lambda/construct.hpp (в хэдере ничего лишнего из boost.lambda).
PC>Нет нельзя. Т.к. ты уже используешь буст вместо написания велосипеда можешь использовать http://www.boost.org/boost/lambda/construct.hpp (в хэдере ничего лишнего из boost.lambda).
Следующий код выдает ошибку 'result_type' : is not a member of 'boost::lambda::constructor<T>':
void main()
{
char *b = "test";
char* e = b + sizeof(b);
string x = bind(constructor<string>(),_1,_2)(b,e);
cout << x << endl;
}
Что я сделал не так?
Здравствуйте, Ароан, Вы писали:
PC>>Нет нельзя. Т.к. ты уже используешь буст вместо написания велосипеда можешь использовать http://www.boost.org/boost/lambda/construct.hpp (в хэдере ничего лишнего из boost.lambda).
А>Следующий код выдает ошибку 'result_type' : is not a member of 'boost::lambda::constructor<T>':
А>void main()
А>{
А> char *b = "test";
А> char* e = b + sizeof(b);
А> string x = bind(constructor<string>(),_1,_2)(b,e);
А> cout << x << endl;
А>}
А>Что я сделал не так?
1.
Вместо
char *b = "test";
char *e = b + sizeof(b);
надо
char b[] = "test";
char *e = b + sizeof(b);
2. int main()
3. Открываем
http://www.boost.org/libs/bind/bind.html#with_function_objects и видим, что для объектов надо явно
указывать возвращаемый тип:
std::string x = boost::bind<std::string>(lambda::constructor<std::string>(),_1,_2)(b,e);
или на старых компиляторах так:
std::string x = boost::bind(boost::type<std::string>, lambda::constructor<std::string>(),_1,_2)(b,e);
4. Чуть ниже там написано — эту операцию можно не производить, если есть result_type. Но его почему-то нет
в lambda::constructor<T>. Это определенно баг, и я обязательно извещу разработчиков буста об этом. А пока в этот шаблон
класса можно добавить строку typedef T result_type; тогда можно будет писать так:
std::string x = boost::bind(lambda::constructor<std::string>(),_1,_2)(b,e);
как ты и хотел.
В результате код станет таким:
#include <boost/bind.hpp>
#include <boost/lambda/construct.hpp>
#include <string>
int main()
{
using namespace boost;
char b[] = "test324324";
char* e = b + sizeof(b);
std::string x = boost::bind(lambda::constructor<std::string>(),_1,_2)(b,e);
std::cout << x << std::endl;
}
P.S. В исходном варианте код работал правильно лишь для строк длиной 4 (на Win-платформе).
т.к. sizeof(T *) == 4.
Спасибо. С бустом все ясно. Вот только не пойму про указатель.
Разьве если писать
char *a = "test for string";
не выделится память под строку в хипе или стеке?
Всегда так писал, вроде ничего...
Здравствуйте, Ароан, Вы писали:
А>Спасибо. С бустом все ясно. Вот только не пойму про указатель.
А>Разьве если писать
А>А>char *a = "test for string";
А>
А>не выделится память под строку в хипе или стеке?
Не в хипе и не в стеке. А в "Const Data" (см.
http://rsdn.ru/Forum/Message.aspx?mid=1663584&only=1Автор: igna
Дата: 07.02.06
). Изменять данные в такой строке ты не можешь. И правильней будет написать так:
const char* = "test for string";
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Здравствуйте, ekamaloff, Вы писали:
E>Не в хипе и не в стеке. А в "Const Data" (см. http://rsdn.ru/Forum/Message.aspx?mid=1663584&only=1Автор: igna
Дата: 07.02.06
).
Нет такого "Const data". Есть static storage и static storage duration и строки как раз находятся там.
E>Изменять данные в такой строке ты не можешь.
Можно. Только будет UB см. 2.13.4/2
E>И правильней будет написать так:
E>E>const char* = "test for string";
E>
+1
Добавлю:
Из C в C++ пришло неявное преобразование const char * в char *. Однако для любих других типов так не сработает:
4.2/2
A string literal (2.13.4) that is not a wide string literal can be converted to an rvalue of type “pointer to
char”; a wide string literal can be converted to an rvalue of type “pointer to wchar_t”. In either case,
the result is a pointer to the first element of the array. This conversion is considered only when there is an
explicit appropriate pointer target type, and not when there is a general need to convert from an lvalue to an
rvalue. [Note: this conversion is deprecated. See Annex D. ] For the purpose of ranking in overload resolution
(13.3.3.1.1), this conversion is considered an array-to-pointer conversion followed by a qualification
conversion (4.4). [Example: "abc" is converted to “pointer to const char” as an array-to-pointer conversion,
and then to “pointer to char” as a qualification conversion. ]
Решил проверить, и Comeau и VC скопилировали это
wchar_t * p = L"test for string";
В чем дело?
Здравствуйте, Pavel Chikulaev, Вы писали:
PC>Решил проверить, и Comeau и VC скопилировали это
PC>PC>wchar_t * p = L"test for string";
PC>
PC>В чем дело? 
Вопрос снят...

туплю читать внимательно надо.