Почему первый конструктор копирования вызывается в коде ниже? - PullRequest
4 голосов
/ 24 января 2012

Почему в конструкции объекта b1?

#include <iostream>
using namespace std;

struct B
{
    int i;
    B() : i(2) { }
    B(B& x) : i(x.i) { cout << "Copy constructor B(B&), i = " << i << endl; }
    B(const B& x) : i(x.i) { cout << "Copy constructor B(const B&), i = " << i << endl; }
};

int main()
{
    B b;
    B b1(b);
}
вместо B(const B&) вызывается B(B&) ctor

Ответы [ 5 ]

6 голосов
/ 24 января 2012

Это потому, что применяется разрешение перегрузки, и поскольку аргумент для конструктора b1 равен b, а b оказывается неконстантным lvalue, тогда выбирается конструктор, принимающий неконстантное lvlalue. И это первый. Интересно, что оба являются конструкторами копирования, но ваш код будет одинаково действителен только с последним.

5 голосов
/ 24 января 2012

Потому что b не является постоянным.Следовательно, он идеально соответствует первому экземпляру ctor, так что это то, что использует компилятор.

2 голосов
/ 24 января 2012

13.3.3.2 / 3 говорит:

Две последовательности неявного преобразования одной и той же формы являются неразличимыми последовательностями преобразования, если не применяется одно из следующих правил:

- Стандартная последовательность преобразования S1лучшая последовательность преобразования, чем стандартная последовательность преобразования S2, если:

S1 и S2 являются ссылочными привязками (8.5.3), а типы, на которые ссылаются ссылки, относятся к одному и тому же типу, за исключением cv-квалификаторов верхнего уровня,и тип, к которому относится ссылка, инициализированная с помощью S2, является более квалифицированным по cv, чем тип, к которому относится ссылка, инициализированная с помощью S1.[Пример:

int f(const int &);
int f(int &);
...
int i;
int j = f(i); // calls f(int&)

В вашем случае, поскольку аргумент является неконстантным, выбирается неконстантная версия копии c-tor, поскольку она лучше соответствует.

1 голос
/ 24 января 2012

Попробуйте это:

int main() {
    const B b;
    B b1(b);
}

Кроме того, трудно принять решение, использовать ли const или нет;)

1 голос
/ 24 января 2012

потому что b не является константой.

...