Конструктор копирования не вызывается для инициализации копирования или не оптимизирован? - PullRequest
1 голос
/ 09 января 2011

Если конструктор копирования сделан private, то в

Случай 1: Без ошибок, компилятору все равно, был ли конструктор копирования определен в классе.

Случай 2: Ошибка, конструктор копирования является частным, и когда он сделан public, он удаляется.

Делает ли он прямую оптимизацию копии, не замечая, что если конструктор былсделано private?

#include <string>
using std::string;

class T
{
    string s;
    T(const T &obj):s(obj.s){}
public:
    T(const string &str):s(str){}
};

int main()
{
    T a = ("Copy Initialization");     //Case: 1

    T b = T("Copy Initialization");    //Case: 2
}

Ответы [ 2 ]

5 голосов
/ 09 января 2011

Случай 2 подпадает под 12,8 / 31 в N3225:

Программа некорректна, если конструктор копирования / перемещения или копирование / перемещение оператор присваивания для объекта неявно odr-используемый и специальный функция-член недоступна.

Тот факт, что копия ctor исключена, не означает, что она не используется odr. 3,2 / 2:

Член набора кандидатов функции используется Odr, если это выбран разрешением перегрузки, когда упоминается из потенциально оцениваемое выражение. [Примечание: это относится к вызовам именованных функции (5.2.2), оператор перегрузка (раздел 13), определяется пользователем преобразования (12.3.2), распределение функция для размещения новых (5.3.4), а а не инициализация по умолчанию (8.5). Копировать конструктор или переместить конструктор используется odr, даже если вызов фактически исключен реализация. —Конечная записка]

Остерегайтесь, конечно, что MSVC не полностью совместим с C ++ 0x, потому что (a) C ++ 0x еще не является стандартом и не завершен; и (b) MSVC все равно не реализовал все до настоящего времени. Но этот материал существенно не изменился по сравнению с C ++ 03, поэтому я вполне уверен, что объяснение остается в силе.

Случай 1 тоже подпадает под это, за исключением того, что на двух компиляторах C ++ 03, которые я проверил, он не зашёл так далеко, потому что нет возможного преобразования строкового литерала в T. Меня это не беспокоит чтобы проверить, разрешены ли в C ++ 0x какие-либо дополнительные последовательности преобразования, в любом месте может быть новое предложение: -)

Для меня до сих пор загадка, почему MSVC допускает случай 1, даже с публичной копией ctor. Позволяет ли это в строгом режиме C ++ 03?

2 голосов
/ 09 января 2011

Случай 1: Нет ошибок , компилятору все равно, был ли задан конструктор копирования в классе.

T a = ("Copy Initialization"); должен выдавать ошибку , поскольку нет подходящего конструктора для преобразования из "const char [20]" в "T"

Вы имели в виду T a = std::string("Copy Initialization");?

Оптимизирует ли она непосредственно копию, не замечая, что если конструктор был закрытым?

Нет, не может. Компиляторы обычно выполняют синтаксический и семантический анализ до фазы оптимизации кода.

...