Допустимо ли делать явную специализацию шаблона с автоматическим возвратом ‘type’ в C ++ 14?

Предыдущий вопрос.

Я повторяю код из предыдущего вопроса, чтобы сделать этот вопрос автономным. Приведенный ниже код компилируется и не выдает никаких предупреждений, если он скомпилирован с использованием gcc 4.8.3. с -std=c++1y, Тем не менее, он выдает предупреждения, если скомпилирован с -std=c++0x флаг. В контексте предыдущего вопроса было указано, что код не компилируется с использованием gcc 4.9.0. К сожалению, в настоящее время я не совсем понимаю, как auto реализовано. Таким образом, я был бы признателен, если бы кто-нибудь мог ответить на следующие вопросы:

1). Является ли приведенный ниже код допустимым C ++ по отношению к стандарту C ++ 14?

2). Если да, можно ли считать этот код хорошим стилем? Если нет, то почему нет?

3). Почему приведенный ниже код компилируется и работает (иногда) при использовании компиляторов C ++ 11? В качестве альтернативы, почему это не всегда работает? Существуют ли какие-либо конкретные флаги / опции / настройки, которые могут помешать его работе?

template<int N> auto getOutputPort2();
template<> auto getOutputPort2<0>();
template<> auto getOutputPort2<1>();

template<>
auto getOutputPort2<0>()
{
return std::unique_ptr<int>(new int(10));
}

template<>
auto getOutputPort2<1>()
{
return std::unique_ptr<string>(new string("qwerty"));
}

5

Решение

1). Является ли приведенный ниже код допустимым C ++ по отношению к стандарту C ++ 14?

Да, насколько я могу судить. Иногда это немного сложно доказать, так как часто это просто ничто не запрещает. Однако, мы можем посмотреть на пример в недавнем черновике (post-N4296), [dcl.spec.auto] / 13:

template <typename T> auto g(T t) { return t; } // #1
template auto g(int);                           // OK, return type is int
template char g(char);                          // error, no matching template
template<> auto g(double);                      // OK, forward declaration with
// unknown return type

В этом же абзаце указано:

Повторные объявления или специализации функции или шаблона функции с объявленным типом возврата, который использует тип заполнителя, также должен использовать этот заполнитель, а не выводимый тип.

Таким образом, явные специализации шаблона функции должен используйте возврат типа возврата.
Я не могу найти ничего, что запрещает разные типы возврата для разных специализаций. Точно так же в C ++ 98 различные возвращаемые типы для специализаций шаблона функции (одного и того же первичного шаблона) могут быть достигнуты, если сделать возвращаемый тип зависимым от аргументов шаблона. Используя метапрограммирование, вы в основном можете добиться того же, что и при использовании вывода типа возвращаемого значения для указания несвязанных типов возвращаемого значения для различных специализаций.


3). Почему приведенный ниже код компилируется и работает (иногда) с использованием компиляторов C ++ 11?

Код в OP плохо сформирован в C ++ 11. Вывод возвращаемого типа для обычных функций (не-lamdas) — это функция, представленная в C ++ 14. Программа, которая содержит этот фрагмент кода плохо формируется. Тем не менее, Стандарт не требует, чтобы реализации (компиляторы) отклоняли некорректно созданные программы. В [intro.compliance] /2.2 просто говорится:

Если программа содержит нарушение какого-либо диагностируемого правила […], соответствующая реализация должна выпустить хотя бы одно диагностическое сообщение.

и в / 8

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

(Таким образом, реализации могут принять эту программу как продолжение.)

g ++ 4.8.3 выдает предупреждение, которое считается диагностическим сообщением. g ++ 4.9 выдает ошибку, которая также является диагностическим сообщением. Оба соответствуют. Указав -WerrorВы могли бы сказать g ++ 4.8.3 отклонить эту программу. (Вы должны спросить разработчиков gcc, почему они изменили это с предупреждения на ошибку.)

6

Другие решения


По вопросам рекламы [email protected]