2013-09-20 6 views
5

Не мог бы кто-нибудь помочь мне понять, почему следующий код не компилируется (g ++ 4.8). Я понимаю, что можно было бы инициализировать PODstd :: is_pod vs subclassing

#include <iostream> 
#include <type_traits> 

struct my_int 
{ 
    int val_; 
}; 
struct B : public my_int 
{ 
}; 

int main() 
{ 
    std::cout << std::is_pod<my_int>::value << std::endl; 
    std::cout << std::is_pod<B>::value << std::endl; 
    const my_int v = { 123 }; 
    //const B v2 = { 123 }; // does not compile with g++ 4.8. 

    return 0; 
} 

компиляции:

g++ -std=c++11 t.cxx 
t.cxx: In function 'int main()': 
t.cxx:24:21: error: could not convert '{123}' from '<brace-enclosed initializer list>' to 'const B' 
    const B v = { 123 }; 
        ^

EDIT:

Спасибо всем ответить теперь я понимаю понятие совокупной инициализации. Я пропустил тот факт, что совокупность не может иметь базовый класс. Поэтому мои текущие планы реализации необходимо изменить. Я хотел сделать что-то вроде:

template < typename T > 
struct base_class 
{ 
    int val_; 
}; 
struct MyInt : public base_class<int> 
{ 
    void Func1() {} 
}; 
struct MyDouble : public base_class<double> 
{ 
    void Func2() {} 
}; 

Я переделок код выше, чтобы избежать использования подкласса вводить специальные функции-члены, избежать дублирования кода.

+0

Вы могли бы добавьте нетривиальный ** не по умолчанию ** ctor, например 'B :: B (int p): my_int (p) {}', который сохраняет статус «B» как POD, но допускает инициализацию 'const B v2 = {123}; '. – dyp

ответ

5

Отказ

Возьмите следующие с зерном соли, поскольку это моя интерпретация вещей. Я отнюдь не специалист. (Также у меня есть некоторые сомнения по поводу агрегата -. Инициализатор списка отношения, которое я заявил здесь)

Ответа

Насколько я могу сказать, что это не представляется возможным, так как совокупная инициализация v2 будет применяться к не агрегат типа класса B.

Из этого answer вы можете считать, что агрегаты не должны иметь базовый класс, который делает B не совокупные и, следовательно, не initializable фигурной скобки прилагается список инициализатора.

С другой стороны, std::is_pod может не работать так, как вы думаете, потому что определение POD изменилось на C++ 11. Поэтому он не дает вам подсказки, если тип, который является POD, может быть инициализирован таким агрегатным инициализатором.

Добавление

Я в основном обсуждали агрегатную инициализацию здесь, но более общий термин для этого является list initialization, который является менее ограничительным.Однако, проверяя все случаи, которые я нашел в связанном ресурсе нет возможности сделать инициализации списка либо , потому что (следующий список ресурса эффектов списка инициализаторов):

  • список инициализатор не пуст
  • B не совокупность
  • B не конкретизацией std::initializer_list
  • B не
    • конструктор принимает список инициализатора
    • конструктор установки подписи списка
  • B не ссылочного типа
  • B не может быть копированием инициализируется из 123 и не прямой инициализации не потому что нет конструктора принимает Int
  • B не значение инициализируется, потому что список инициализатора IST не пуст
+0

Visual C++ 2013 RC поддерживает вашу теорию: Microsoft (R) C/C++ Оптимизация компилятора Версия 17.00.60610.1 для x64 Авторское право (C) Корпорация Microsoft. Все права защищены. test.cpp test.cpp (18): ошибка C2552: 'v2': не-агрегаты не могут быть инициализированы с иней списка tializer 'B': Типы с основанием не совокупности – jschroedl

+0

@jschroedl: лязг 3.3 сказала что-то подобное ('non-aggregate type 'const B' не может быть инициализировано с помощью списка инициализаторов '), но мне не нравится использование выводов компилятора для рассуждений, потому что они могут отклоняться от стандарта. – Nobody

+0

Возможно, вам нужно ссылаться на [C++ 11 answer] (http://stackoverflow.com/a/7189821/420683) на тот же вопрос вместо определения агрегатов. Кроме того, я согласен с вашим анализом стандарта ([dcl.init.list]/3). 'const my_int v = {123};' is list-initialization, но он не выполняет (разрешать) агрегацию-инициализацию, потому что 'my_int' не является агрегированным. Единственный доступный ctor - это по умолчанию ctor и copy/move ctor, но они не могут использоваться с аргументом типа 'int'. Объект, который будет инициализирован, относится к типу класса и не содержит ссылки. Программа Ergo плохо сформирована. – dyp

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