Использование идентификатора структуры для обозначения типов POD и структур C

Рассмотрим следующий фрагмент кода:

struct Foo {};

template<typename ForwardIterator>
struct Foo*
Bar(ForwardIterator first, ForwardIterator last)
{ 
    (void)first;
    (void)last;
    Foo *foo(nullptr);
    return foo;
}

Приведенный выше фрагмент кода отлично компилируется в Clangv3.5 и GCCv4.9.

Однако он не компилируется в VC++2013.

Удаление идентификатора struct (см. ниже) из возвращаемого типа решает проблему:

struct Foo {};

template<typename ForwardIterator>
Foo*
Bar(ForwardIterator first, ForwardIterator last)
{ 
    (void)first;
    (void)last;
    Foo *foo(nullptr);
    return foo;
}

Q1:

Это баг визуальной студии?

Вопрос 2:

Эта проблема возникла из-за того, что в моей кодовой базе Foo struct находится в файле .h.c (т. е. является C struct), и для обозначения C/POD struct в моем коде я использую идентификатор struct. Является ли это плохой идеей (т.е. в коде C++ я должен избегать использования идентификатора struct таким образом)?


person 101010    schedule 05.11.2014    source источник
comment
Я часто использую struct в чистом коде C++, в частности, если нет private или protected элементов или баз.   -  person Walter    schedule 05.11.2014
comment
@Walter Вопрос не в этом. Это не struct против class.   -  person Konrad Rudolph    schedule 05.11.2014
comment
@КонрадРудольф Правда? Я думал, что Q2 по сути был Является ли использование struct исключительно для POD хорошей идеей? (Если не использовать исключительно для этой цели, то все это не имеет смысла.)   -  person Walter    schedule 05.11.2014
comment
Дайте мне знать, заполнили вы отчет об ошибке или нет, в противном случае я отправлю его.   -  person Shafik Yaghmour    schedule 06.11.2014
comment
@ShafikYaghmour Нет, не стесняйтесь :).   -  person 101010    schedule 06.11.2014
comment
@Walter А, я вижу путаницу. Учитывая контекст, я думаю, что OP знает разницу между struct и class, и что Q2 спрашивает, является ли хорошей идеей использовать префикс использования данного имени структуры с ключевым словом struct (как это необходимо сделать в C).   -  person Konrad Rudolph    schedule 06.11.2014
comment
Я подал отчет об ошибке, ссылка на него есть в моем ответе.   -  person Shafik Yaghmour    schedule 06.11.2014


Ответы (1)


Основная цель уточненных спецификаторов типов – позволить вам обратиться к скрытому имени из черновик стандарта C++, раздел 3.4.4 Доработанные спецификаторы типов:

Уточненный спецификатор-типа (7.1.6.3) может использоваться для ссылки на ранее объявленное имя-класса или имя-перечисления, даже если это имя было скрыто объявлением не-типа (3.3.10).

и поэтому в случае, когда Foo скрыто, вам придется использовать усложненные спецификаторы типа:

struct Foo {};

void Foo()
{
}

Я не вижу ничего в 7.1.6.3 Проработанных спецификаторах типов или 14 Шаблонах, что могло бы воспрепятствовать такому использованию. На самом деле, судя по описанию CS2989, Visual Studio путается и думает, что вы пытаетесь переопределить класс, не являющийся шаблоном, как класс шаблона.

Так что мне это кажется ошибкой, поэтому я бы отправил отчет об ошибке.

Обновить

Зарегистрирована функция отчет об ошибке.

person Shafik Yaghmour    schedule 05.11.2014