2017-02-02 12 views
8

мне было интересно в следующем было законным в соответствии со стандартом C++:Имеет ли заголовок функции, возвращающий абстрактный тип права?

struct Abstract { virtual ~Abstract() = 0; }; 

auto get_type() -> Abstract; 

// I use `get_type` only to extract the return type. 
using MyType = decltype(get_type()); 

НКУ 6,3 принять его, но Clang 3,9 отклонить его.

Однако, если я делаю это вместо:

auto get_type() -> struct Abstract; 

struct Abstract { virtual ~Abstract() = 0; }; 

using MyType = decltype(get_type()); 

Теперь и компилятор принимает его. Они оба ошибаются в этом случае?

+0

Функция 'get_type()' никогда не вызывается? И 'MyType' никогда не используется за пределами указателя или ссылки? Я думаю, что все в порядке. Компилятор отбрасывает все неиспользуемые вещи. – AndyG

+2

Использование 'struct Abstract {virtual ~ Abstract() = 0; }; Abstract test(); '- проблема в g ++, но с использованием' struct Abstract {virtual ~ Abstract() = 0; }; auto test() -> Abstract; 'is not. Я не думаю, что компилятор должен вести себя по-другому для этих двух. Я думаю, это указывает на ошибку компилятора. –

+0

* "** [class.abstract]/3 ** Абстрактный класс не должен использоваться как тип параметра, как возвращаемый тип функции или как тип явного преобразования." * Я считаю, что это делает ваш первый пример плохо сформированный, и GCC ошибается, чтобы принять его. Во втором примере 'Abstract' является неполным типом в точке, которая используется как возвращаемый тип; он пока не известен как абстрактный класс. –

ответ

10

В [class.abstract], довольно прямолинейно:

An abstract class shall not be used as a parameter type, as a function return type, or as the type of an explicit conversion.

Любой код, который пытается сделать такую ​​вещь плохо сформированным.

+0

Кроме того, 7.1.6.4/s [dcl.spec.auto] не освобождает функцию get_type в этом сценарии, потому что «Если декларатор функции включает в себя тип trailing-return-type, который указывает объявленный тип возвращаемого значения функции" – AndyG

+0

@Barry Даже мой второй пример незаконен? Таким образом, оба компилятора ошибочны? –

+0

@GuillaumeRacicot Да, он все еще использует абстрактный класс как возвращаемый тип функции. – Barry