Времена не ведут себя как постоянные - PullRequest
1 голос
/ 16 ноября 2011

Мне неясно, принимает ли временный тип const или нет, в выражении, как показано ниже.

#include <iostream>

class X {
public:
X(int a) { i = a; cout << "X(int) [" << (int)this << "]" << endl; }

X& operator+(const X& x) 
{ 
i += x.i; 
cout << "X operator+(const X&) [" << (int)this << "]" << endl; 
return *this; 
}

~X() { cout << "~X [" << (int)this << "]" << endl; }

private:
int i;
};


int main() 
{
X x = X(3) + X(4);
cout << "done" << endl;

return 0;
}

X(3) ведет себя как неконстантный (потому что я могу вызвать operator+, в то время как X(4) ведет себя как констант (потому что ему нужен аргумент const в operator+).

Может кто-нибудь уточнить, что такое правильное понимание?

Ответы [ 4 ]

2 голосов
/ 16 ноября 2011

Исторически временные значения являются r-значениями, а r-значения не являются (и не могут быть) резюме квалифицированных. Это правило хорошо работает для не классовых типов или для класса типы без функций-членов; так как постоянство вмешивается в функцию разрешение перегрузки, cv-квалификация временного должна быть поддерживается. Если функция возвращает просто X, тогда временный not const, и вы можете вызывать неконстантные функции для него; если функции возвращают X const, тогда временный констант, и вы не можете вызовите неконстантные функции на нем. Как правило, это, вероятно, предпочтительнее возвращать типы классов как const; то есть X const f(), скорее чем X f(). Но есть определенные исключения, и никто не делает этого, даже в тех случаях, когда это было бы более уместно. И наконец, существуют контексты, в которых нельзя указать функцию const-ness & mdash; преобразования типов стилей, например & mdash; где синтаксис не предоставить возможность указания cv-квалификаторов (кроме использования typedef).

Возможно, вы захотите посмотреть на вывод следующего кода:

class C
{
    std::string myComment;
public:
    C( std::string const& comment ) : myComment( comment ) {}

    void f()
    {
        std::cout << "Non const " << myComment << std::endl;
    }

    void f() const
    {
        std::cout << "Const " << myComment << std::endl;
    }
};

typedef C const CC;

C
c()
{
    return C("function return value");
}

C const
cc()
{
    return C("function return value");
}

int
main()
{
    C("function style conversion").f();
    CC("function style conversion").f();
    c().f();
    cc().f();
}
2 голосов
/ 16 ноября 2011

Когда речь идет о типах классов, при создании временного типа const этот временный будет const. И когда вы создаете временный неконстантный тип, он будет неконстантным. Вот и все. То есть Что касается точного типа, то здесь вообще нет связи между const и временными. Временный тип класса никогда не принимает const сам по себе. Это вы можете явно навязать ему const.

В вашем примере, nether X(3) и X(4) не являются постоянными. Поскольку X(3) не является константой, вы можете вызвать неконстантный метод для него.

Неправильно говорить, что ваш X(4) "ведет себя как const". Нет никаких признаков того, что он "ведет себя как постоянный" в вашем примере. То, что вы смогли инициализировать константную ссылку чем-то, не означает, что это константное что-то.

В своем вопросе вы утверждаете, что вам "нужен аргумент const в operator+". Это неверно Вам не нужен const аргумент в вашем operator+. Ваш параметр x объявлен как постоянная ссылка. Ссылка на const может быть легко связана с аргументами const, а также с неконстантными аргументами. В вашем случае параметр константной ссылки x связан с неконстантным временным аргументом X(4).

2 голосов
/ 16 ноября 2011

Вы можете позвонить не- const членам временных. Но вы не можете привязать не-const ссылку к временному.

1 голос
/ 16 ноября 2011

В следующем коде:

X x = X(3) + X(4);

X(3) создает временный неконстантный объект, который вызывает operator+, передавая X(4), который является другим временным неконстантным объектом в качестве аргумента константной ссылки дляфункция.

Неконстантный объект может быть передан функции как константный объект (передача по ссылке), но константный объект не может быть передан по неконстантной ссылке на функцию.В этом разница.

...