[c++] присваивание временной переменной
Как сделать чтобы ругался?Удалить copy constructor?
хочу чтобы компилятор не давал присваивать во временные значения, хотя бы warning писал.
Удалить copy constructor?а разве тут copy constructor будет вызываться?
не operator=?
а разве тут copy constructor будет вызываться?Да нет, это я так.
Сделать explicit copy constructor и забанить оператор =.
Пример:
class A
{
public:
void operator << (const A&) { }
};
void operator < (A&, const A&) { }
void test
{
A a;
A << a;
A < a; // no match for 'operator<' in 'A < a'
}
почему такое возможно и на это не ругается компилятор?http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n324...
Как сделать чтобы ругался?Могу в качестве развратного рецепта предложить запретить использовать внутренные конструкторы и перейти к внешним:
#include <string>
inline const std::string stdString { return std::string; }
inline const std::string stdString(char const *s) { return std::string(s); }
int main {
std::string s(stdString("test";
stdString = s;
return 0;
}
(Первая строчка в мейне не то чтобы конструкция, она просто для демонстрации того, что присваивание именованным объектам по-прежнему работает, а все temporaries, см. следующую строчку, теперь константные.)
Но это стайлгайд переделывать.
почему такое возможно и на это не ругается компилятор? Как сделать чтобы ругался?надо с этим жить
смотри на это, как на вызов неконст метода у временного объекта.
std::string.do_something(bla-bla);
не вижу причин запрещать такое или даже выдавать предупреждение
Да нет, это я так.лично для меня было не очевидно что же реально используется
оказалось, что если имя у переменной есть, то работает copy initialization, а если безымянный объект, то срабатывает конструктор + operator=
смотрим:
http://liveworkspace.org/code/4hfkIi%243
оказалось, что если имя у переменной есть, то работает copy initialization, а если безымянный объект, то срабатывает конструктор + operator=Да дело даже не в имени.
смотрим:
Просто std::string — это выражение, результат которого есть уже готовая строка, поэтому там assignment operator.
В std::string s = std::string никаких таких выражений слева нет, именованный объект, остается только семантика конструкции.
void operator < (A&, const A&) { }Гениально - давайте запретим сравнивать константные объекты.
а почему, кстати, не вызывается этот оператор-то? Т.е. присвоить можно, а оператор < такой вызвать нельзя, в чем прикол?
вообще-то это он для примера оператор перегрузил, никто не предлагает запрещать сравнивать.
1.cc:15:7: error: invalid operands to binary expression ('A' and 'A')
A < a;
~~~ ^ ~
1.cc:7:6: note: candidate function not viable: expects an l-value for 1st argument
bool operator<(A&, const A&) {
^
Точно так же нельзя написать
A& ref = A;
error: non-const lvalue reference to type 'A' cannot bind to a temporary of type 'A'
A& ref = A;
^ ~~~
а почему, кстати, не вызывается этот оператор-то? Т.е. присвоить можно, а оператор < такой вызвать нельзя, в чем прикол?Тут есть немного флуда на эту тему: http://stackoverflow.com/questions/1565600/how-come-a-non-const-reference-cannot-bind-to-a-temporary-object
Вкратце:
The C++ committee decided it doesn't make sense to modify temporaries, therefore, they disallowed binding to non-const references.Но для операторов-членов класса это ограничение не работает, так как this при вызове метода передаётся просто как указатель (если я правильно понимаю).
так как this при вызове метода передаётся просто как указатель (если я правильно понимаю).константность this определяется же по тому, стоит после метода квалификатор const или нет.
ну в принципе ответ на SO меня устроил, просто не знал о такой особенности, спасибо.
Оставить комментарий
elenangel
почему такое возможно и на это не ругается компилятор? Как сделать чтобы ругался?