Можно забиндить конструктор?
От: Ароан Россия  
Дата: 05.02.06 12:28
Оценка:
Есть такой конструктор 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);
    }
};


Спасибо.
Re: Можно забиндить конструктор?
От: Pavel Chikulaev Россия  
Дата: 05.02.06 15:26
Оценка:
Здравствуйте, Ароан, Вы писали:

А>Есть такой конструктор string(const char *, const char *), можно его как-то забиндить, чтобы не писать обертку RangeToString.


Нет нельзя. Т.к. ты уже используешь буст вместо написания велосипеда можешь использовать http://www.boost.org/boost/lambda/construct.hpp (в хэдере ничего лишнего из boost.lambda).
Re[2]: Можно забиндить конструктор?
От: Ароан Россия  
Дата: 08.02.06 11:08
Оценка:
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;
}


Что я сделал не так?
Можно забиндить конструктор?
От: Pavel Chikulaev Россия  
Дата: 08.02.06 12:29
Оценка:
#Имя: FAQ.cpp.lambda.constructor
Здравствуйте, Ароан, Вы писали:

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.
Re[4]: Можно забиндить конструктор?
От: Ароан Россия  
Дата: 08.02.06 12:43
Оценка:
Спасибо. С бустом все ясно. Вот только не пойму про указатель.
Разьве если писать
char *a = "test for string";

не выделится память под строку в хипе или стеке?
Всегда так писал, вроде ничего...
Re[5]: Можно забиндить конструктор?
От: ekamaloff Великобритания  
Дата: 08.02.06 12:47
Оценка:
Здравствуйте, Ароан, Вы писали:

А>Спасибо. С бустом все ясно. Вот только не пойму про указатель.

А>Разьве если писать
А>
А>char *a = "test for string";
А>

А>не выделится память под строку в хипе или стеке?

Не в хипе и не в стеке. А в "Const Data" (см. http://rsdn.ru/Forum/Message.aspx?mid=1663584&amp;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
Re[6]: Можно забиндить конструктор?
От: Pavel Chikulaev Россия  
Дата: 08.02.06 13:05
Оценка:
Здравствуйте, ekamaloff, Вы писали:

E>Не в хипе и не в стеке. А в "Const Data" (см. http://rsdn.ru/Forum/Message.aspx?mid=1663584&amp;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";

В чем дело?
Re[7]: Можно забиндить конструктор?
От: Pavel Chikulaev Россия  
Дата: 08.02.06 13:07
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

PC>Решил проверить, и Comeau и VC скопилировали это

PC>
PC>wchar_t * p = L"test for string";
PC>

PC>В чем дело?
Вопрос снят... туплю читать внимательно надо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.