Это довольно сложный вопрос, и может случиться так, что VisualStudio прав, и Комо ошибается (это кажется очень трудно поверить).
Стандарт, если читать слово за словом, определяет, что вектор конструктор в терминах конструктора копирования (см цитаты), и что в буквальном смысле означает, что объект, полученный путем разыменования итератора сначала должен быть преобразован в тип Т и то должен быть вызван конструктор копирования. На этом этапе с явным конструктором код не должен компилироваться.
С другой стороны, представляется разумным ожидать, что реализация напрямую вызовет конструктор, принимающий в качестве аргумента разыменованный итератор, и в этом случае вызов конструктора будет явным и, следовательно, код должен быть скомпилирован.Это противоречило бы точной формулировке в приведенной ниже цитате, как конструктор копии определяется для данного типа T, как конструктор, который принимает один, возможно, постоянную ссылку на объект типа T.
Я не могу думать о любой разумный аргумент не использовать подход Комоу, и я полагаю (это просто личное мнение) заключается в том, что формулировка в стандарте относительно сложности векторного конструктора, вероятно, должна быть скорректирована, так как требуется только N вызовов к соответствующему T конструктор, где это необходимо, должен быть определен как конструктор, который соответствует вызову T(*first)
(то есть либо конструктор, принимающий InputIterator::value_type
(по значению или, возможно, постоянную ссылку), либо копию T const ructor после того, как неявное преобразование из InputIterator::value_type
к T.
23.2.4.1 [lib.vector.cons]/1
Сложность: Шаблон Конструктор вектор (InputIterator первый, InputIterator последний) составляет только N вызывает конструктор копирования T (где N - это расстояние между первым и последним) и не перераспределяет , если итераторы первого и последнего из переадресации, двунаправленного или случайного категорий доступа. Он делает порядок N вызывает конструктор копирования T и журнал заказов N перераспределений, если они просто вводят итераторы.
Я хотел бы знать, как компилятор VS ведет себя при Дано:
struct T1;
struct T2 {
operator T1();
};
struct T1 {
T1(T2 const &) { std::cout << "T1(T2)" << std::endl; }
};
T2::operator T1() {
std::cout << "T2::operator T1" << std::endl;
return T1(*this);
}
int main() {
std::vector<T2> v2;
v2.push_back(T2());
std::vector<T1> v1(v2.begin(), v2.end());
}
С г ++ результат в том, что T2::operator T1
не называется, а элементы в v1
построены непосредственно из элементов v2
. Я бы предположил, что с VS компилятор будет использовать T2::operator T1
для преобразования из каждого элемента в v2
в элемент T1, а затем вызывает конструктор копирования. Это так?
Непосредственно ответил здесь: http://stackoverflow.com/questions/1943228/implicit-constructor-conversion-works-on-explicit-vectorvector-only-sometimes –
Я просто написал ответ здесь, основываясь на этом вопросе + ответе, но это действительно не применяется, поскольку 'std :: vector :: iterator' не является интегральным типом, и конструктор заполнения не вызывается. Поэтому я удалил его. Я думаю, что все, что я могу сказать, это то, что стандарт не запрещает * явное преобразование в любом конструкторе контейнера. –
Potatoswatter
VS 2010 Beta ведет себя как Comeau и gcc. –