Вот этот код компиляется в gcc --pedantic, icl /Za, cl /Za
Только icc выдает warning
test4.cpp(8): warning #597: "X::operator X &()" will not be called for implicit or explicit conversions
struct X
{
operator X&()
{
return *this;
}
};
X get_X()
{
return X();
}
X &operator <<(/*note: non const reference!*/ X &x, int)
{
return x;
}
void f()
{
get_X() << 1 << 2 << 3;
}
Если этот operator X& убрать, то gcc ругается, что не может передать rvalue X по неконстантной ссылке.
test4.cpp:26: error: no match for 'operator<<' in 'get_X() << 1'
test4.cpp:20: note: candidates are: X& operator<<(X&, int)
Так что он нужен, и он вызывается. Что же icl плачется?
Теперь проблема в msvc.
Вот этот код компиляется в gcc/icc, но не компилируется в msvc8.0/7.1:
template <class OutIter>
struct text_out_t
{
operator text_out_t&()
{
return *this;
}
};
template <class OutIter>
text_out_t<OutIter> &operator <<(text_out_t<OutIter> &to, int)
{
return to;
}
template <class OutIter>
text_out_t<OutIter>
text_out()
{
return text_out_t<OutIter> ();
}
int main()
{
text_out<char *>() << 1 << 2 <<3;
}
Почему ic++ дает странный warning?
Корректно ли operator ThisType &() { return *this; } по стандарту?
Как заставить компилироваться это на msvc?
Я вижу только три выхода, и они мне все не нравяться —
1) сделать член у класса text_out_t вроде ref
text_out_t &ref()
{
return *this;
}
нужен непонятный для пользователя tex_out().
ref() << 1 << 2<< 3;
2)
Сделать все члены text_out_t как mutable, в operator << передавать по константной ссылке.
Не хочется этого делать, так как таких операторов много, писать по два лишних const (и, что более важно, не логичных) заставлять юзера тоже не хочу.
3) всегда передавать по значению.
Тоже не хочу, text_out_t может стать "тяжелым" классом с 5-10 членами.
Посоветуйте.
Ага, como тоже не компиляет.
Как же удобней всего выйти из ситуации?
Здравствуйте, Centaur, Вы писали:
C>Если объект тяжело копировать, можно над ним написать smart reference. Такой класс с одним указателем на настоящий объект, и куча форвардящих функций. Smart reference копировать легко.
Мне надо его возвращать из функций
Не создавать же его на хипе из-за этого?
В связи с этим родился такой "шедевр":
struct persistent_format_options_t
{
//pack field as possible, text_out_t often passed/returned by value.
uint32_t m_zero_pad : 8;
uint32_t m_precision : 8;
uint32_t m_pos_sign : 2;
uint32_t m_alternavive : 1; //not implemented yet
uint32_t m_thousand_separator : 1; //not implemented yet
enum positive_sign_t { e_ps_none = 0 , e_ps_plus = 1, e_ps_space = 2};
positive_sign_t get_positive_sign()
{
return positive_sign_t(m_pos_sign);
}
positive_sign_t set_positive_sign(positive_sign_t in_pos_sign)
{
m_pos_sign = in_pos_sign;
}
persistent_format_options_t()
:m_zero_pad(0)
,m_precision(6)
,m_pos_sign(e_ps_none)
,m_alternavive(false)
,m_thousand_separator(false)
{
}
};
Если станет совсем невмоготу, придется делать все члены mutable, а все передачи по значению заменить на const ref