2016-06-11 4 views
6

Является ли следующий код законным?Является ли итератором контейнер с неполным типом данных законным?

class A 
{ 
    std::map<int, A>::iterator x; 
}; 

Visual Studio 2015 принимает его, но лязг говорит

.../ndk/sources/cxx-stl/llvm-libc++/libcxx/include/utility:254:9: 
error: field has incomplete type 'A' 
    _T2 second; 
    ^
.... 
a.cpp:52:21: 
note: definition of 'A' is not complete until the closing '}' 
    struct A 
     ^

Edit:
Проблема, кажется, со стандартной библиотекой, http://rextester.com/QNNEG57036 терпит неудачу на этом

Мой вопрос, является ли код является законным или нет, а не как его исправить (например, изменением флагов компилятора).

+0

clang 3.8 компилирует такой код без ошибок – fghj

+0

@ user1034749: Я не проверял, в каком контейнере он на самом деле жалуется только на карту – Dani

+0

Жалуется ли он на список? –

ответ

4

Если в стандарте не указано, что неполные типы являются законными, они не являются законными. Конкретный раздел 17.6.4.8 [res.on.functions] пункт 2:

В частности, эффекты не определены в следующих случаях:

[...]

  • если неполный тип (3.9) используется в качестве аргумента шаблона при создании экземпляра компонента шаблона, если это специально не разрешено для этого компонента.

Я не думаю, что для поддержки неполных типов не требуется никаких контейнеров. Некоторые из интеллектуальных указателей допускают неполные типы. Вне рук я не могу придумать ничего другого, что позволило бы неполные типы. Быстрый поиск "неполный" дает следующие компоненты позволяют неполные типы в качестве аргументов шаблона:

  • std::declval<T>()
  • std::unique_ptr<T>
  • std::default_delete<T>
  • std::shared_ptr<T>
  • std::weak_ptr<T>
  • std::enable_shared_from_this<T>

В примере кода std::map<int, A>::iterator создает экземпляр шаблона с неполным типом. В результате код приводит к неопределенному поведению.

+0

Векторный, список и поддержка forward_list неполных типов. – Barry

+0

@Barry: Есть ли у них полный список? – Dani

+0

@ Дани [здесь] (http://eel.is/c++draft/containers), найдите _incomplete_, и вы найдете их (я имею в виду три контейнера, упомянутых @Barry). – skypjack

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