Конструкторы: разница между дефолтом и делегированием параметра
Сегодня я наткнулся на эти стандартные объявления конструкторов std::vector
:
// until C++14
explicit vector( const Allocator& alloc = Allocator() );
// since C++14
vector() : vector( Allocator() ) {}
explicit vector( const Allocator& alloc );
Это изменение можно увидеть в большинстве стандартных контейнеров. Немного другой пример: std::set
:
// until C++14
explicit set( const Compare& comp = Compare(),
const Allocator& alloc = Allocator() );
// since C++14
set() : set( Compare() ) {}
explicit set( const Compare& comp,
const Allocator& alloc = Allocator() );
В чем разница между двумя шаблонами и каковы их преимущества?
Являются ли они строго эквивалентными - компилятор генерирует нечто подобное второму из первого?
Ответы
Ответ 1
Отличие состоит в том, что
explicit vector( const Allocator& alloc = Allocator() );
является explicit
даже для случая, когда используется аргумент по умолчанию, а
vector() : vector( Allocator() ) {}
нет. (explicit
в первом случае необходимо, чтобы Allocator
неявно был конвертирован в vector
.)
Это означает, что вы можете написать
std::vector<int> f() { return {}; }
или
std::vector<int> vec = {};
во втором случае, но не в первом.
См. LWG-выпуск 2193.