2015-03-07 5 views
1

Рассмотрим кода, связанный с предыдущей SO вопроса C++ cyclic dependency confusion with adjacency list representationнеполный типа для станд :: unordered_set ошибка компиляции в г ++ 5, компилируется в звоне ++

#include <cstddef> 
#include <unordered_set> 

class Node; 

class Hash { 
public: 
    std::size_t operator()(const Node &node) const; 
}; 

class Node { 
public: 
    int data; 
    std::unordered_set<Node, Hash> links; 
}; 

inline size_t Hash::operator()(const Node &node) const { 
    return node.data; 
} 

int main() 
{ 

} 

Этот код не компилируется при использовании г ++ 4.9. 2 или g ++ 5, однако компилируется с помощью clang ++ 3.5.

Ошибка выплюнуть на г ++ начинается с

error: invalid application of 'sizeof' to incomplete type 'Node' : std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value>

Вопрос: Должен ли быть полный тип Node при объявлении std::unordered_set? Похоже, что g ++ или clang ++ в этом случае не так.

PS: Я знаю, что этой ситуации можно избежать, используя вместо этого, однако хотелось бы понять поведение в приведенном выше коде.

ответ

8

Неопределенное поведение для создания экземпляра контейнера стандартной библиотеки с неполным типом. [Res.on.functions]/1, 2,5:

1 В некоторых случаях (замена функций, функций обработчика, операции над типами используемых для создания экземпляра стандартной библиотеки шаблонов компонентов), С ++ стандартная библиотека зависит от компонентов поставил программой C++. Если эти компоненты не отвечают их требованиям, в Стандарте не предусмотрены требования к реализации.

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

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

Обе реализации верны.

Существует в настоящее время proposal добавить неполную поддержку типов в некоторых контейнерах, но оно ограничено vector, list и forward_list.

+0

hmm, clang ++ даже не плюет предупреждение, 'clang ++ -std = C++ 11 -Wall -Wextra -Wpedantic so.cpp' – vsoftco

+0

_ +1: Я не вижу ничего, чтобы оспаривать этот ответ. –

+0

@ T.C. спасибо, место на. Я знал, что были проблемы с 'std :: vector' из довольно старой статьи на C++ http://www.drdobbs.com/the-standard-librarian-containers-of-inc/184403814, но не знал, что теперь стандарт явно запрещает использование неполных типов везде (если только это не разрешено). – vsoftco