2013-07-29 3 views
1
#include <iostream> 
using namespace std; 

struct Point 
{ 
    int x; 
    int y; 
}; 

int main() 
{ 
    //Point p(2, 3); // error: no matching constructor for initialization of 'Point' 
    Point p{2, 3}; // fine 
} 

Вопрос> Верно ли, что если мы будем использовать равномерную инициализации для инициализации переменной, то мы не должны определить соответствующий явный конструктор? Как показано в приведенном выше примере, класс Point не имеет конструктора с двумя параметрами пропуска, но равномерная инициализация все еще работает. Я чувствую смущение здесь и хочу знать ответ на мой вопрос.Почему равномерная инициализация работает без явного конструктора

Спасибо

+1

«Явный конструктор» не означает, что вы думаете, что это значит. Вы имеете в виду, без пользовательского конструктора. Ваш тип является агрегатом, и даже C (и C++ 89, C++ 03) могут инициализировать те, у которых _brace-initialization_ – sehe

+0

@sehe: Я не согласен с тем, что это дубликат. * Ответы * могут быть одинаковыми (или похожими, так как это всего лишь агрегаты, а не POD), но вопросы очень разные. –

+1

Для меня «явный конструктор» означает написанный пользователем конструктор. Однако «явный конструктор» для меня означает конструктор, объявленный с «явным» ключевым словом или чем-то эквивалентным (неявно объявленный наследуемый конструктор с таким «явным» значением, например,). –

ответ

3

Цели равномерной инициализации является быть единственным средством инициализации любого объекта, который может быть инициализирован. Поэтому он может выбрать и выбрать соответствующий механизм инициализации для внутреннего использования для определенного типа.

Point является aggregate. В C++ 98/03 он может быть инициализирован с помощью агрегатной инициализации, подобно массиву.

Point p = {3, 4}; 

Это было законно в C++ 98/03.

В C++ 11 инициализация агрегата является одним из возможных способов инициализации единой инициализации переменной. Если инициализированный тип является агрегатом, то члены списка с привязкой-инициализацией используются для инициализации посредством агрегатной инициализации. Но агрегатная инициализация в C++ 98/03 работала только в форме Typename var = braced-init-list;. Равномерная инициализация позволяет всем эти формы, чтобы использовать его, а также:

Point p{3, 4}; 

void Func(const Point &p); 
Func({3, 4}); 

Point Func2() 
{ 
    return {3, 4}; 
} 

Все они используют единообразное инициализации для инициализации Point агрегата. Однако, поскольку он использует единый синтаксис инициализации, вы можете позже изменить Point, чтобы добавить конструктор. И до тех пор, пока вы добавляете конструктор, который принимает два целых числа (и не добавить конструктор initializer_list, который принимает целые числа), весь ваш код будет работать нормально.

Смежные вопросы